使用dispatchgroup在for循环中等待任务完成,如果失败则退出循环



我正试图根据条件退出for循环,但我遇到了问题,因为它甚至没有退出循环。这是我的代码循环。

var isFailure = true
let dispatchGroup = DispatchGroup()
var myFailureTask: Int?
for item in 1...5 {
dispatchGroup.enter()
test(item: item, completion: {
print("Success(item)")
dispatchGroup.leave()
}, failureBlock: {
print("Failure(item)")
myFailureTask = item
dispatchGroup.leave()
return
})
dispatchGroup.wait()
}
dispatchGroup.notify(queue: .main) {
if let myFailure = myFailureTask {
print("task failure (myFailure)")
} else {
print("all task done")
}
}
func test(item: Int,completion: @escaping(() -> ()), failureBlock: @escaping(() -> ())) {
Thread.sleep(forTimeInterval: TimeInterval(item))
isFailure = !isFailure
if isFailure {
failureBlock()
} else {
completion()
}
}

return从当前作用域返回。

在这种情况下,它从failureBlock: {}返回,而不是从for循环作用域返回。

你必须重构代码来实现你想要做的事情

或者(如果此代码是同步执行的(,您可以通过使function的返回类型为Bool并删除failureBlock参数,从函数中返回successtrue|false

或者(如果此代码是异步执行的(,您必须考虑在触发另一个任务之前等待一个任务完成/失败。

更新

我认为下面可能是这个代码的简化版本-

var isFailure: Bool = false
func callTest(for item: Int) {
print("task initiated (item)")
test(item: item, completion: {
print("task succeeded (item)")
if item < 5 {
callTest(for: item+1)
} else {
print("all tasks done")
}
}, failureBlock: {
print("task failed (item)")
})
}
func test(item: Int, completion: @escaping (() -> Void), failureBlock: @escaping (() -> Void)) {
Thread.sleep(forTimeInterval: TimeInterval(item))
isFailure.toggle()
if isFailure {
failureBlock()
} else {
completion()
}
}
callTest(for: 1)
var isFailure = false
let dispatchGroup = DispatchGroup()
var myFailureTask: Int?
for item in 1...5 {
dispatchGroup.enter()
test(item: item, completion: {
print("Success(item)")
dispatchGroup.leave()
}, failureBlock: {
print("Failure(item)")
myFailureTask = item
dispatchGroup.leave()
})
if isFailure == true {
break
}
dispatchGroup.wait()
}
dispatchGroup.notify(queue: .main) {
if let myFailure = myFailureTask {
print("task failure (myFailure)")
} else {
print("all task done")
}
}
func test(item: Int,completion: @escaping(() -> ()), failureBlock: @escaping(() -> ())) {
Thread.sleep(forTimeInterval: TimeInterval(item))
isFailure = !isFailure
if isFailure {
failureBlock()
} else {
completion()
}
}```
Made few changes work like a charm.
Any one has better idea please comment

最新更新