当两个其他完成块被调用时调用完成块 [英] Call completion block when two other completion blocks have been called
问题描述
我有一个函数 doEverything
需要一个完成块.它调用另外两个函数,doAlpha
和 doBeta
,它们都有完成块.这两个函数应该异步运行.我想在其他两个函数都调用了它们的完成块之后调用 doEverything
的完成块.
I have a function doEverything
that takes a completion block. It calls two other functions, doAlpha
and doBeta
which both have completion blocks. These two functions should run asynchronously. I want to call doEverything
's completion block after both of the other functions have called their completion blocks.
目前,它看起来像这样:
Currently, it looks like this:
func doEverything(completion: @escaping (success) -> ())) {
var alphaSuccess = false
var betaSuccess = false
doAlpha { success in
alphaSuccess = success
}
doBeta { success in
betaSuccess = success
}
// We need to wait here
completion(alphaSuccess && betaSuccess)
}
doAlpha
和 doBeta
应该同时运行,一旦它们都完成,完成块应该用 alpha 和 beta 的结果调用.
doAlpha
and doBeta
should run at the same time and, once they've both completed, the completion block should be called with the result of alpha and beta.
我已经阅读了调度组和障碍,但我不确定哪个是最合适的,它们如何引入新的范围(关于我正在使用的两个变量)以及我应该如何实现它.
I've read into dispatch groups and barriers but I'm not sure which is the most appropriate, how they both introduce new scope (with regards to the two variables I'm using) and how I should implement that.
非常感谢.
推荐答案
Grand Central Dispatch (GCD) 是您在此处尝试执行的操作的不错选择,您可以使用 DispatchQueue 和 DispatchGroup,如下:
Grand Central Dispatch (GCD) is a pretty good choice of what are you trying to do here, you can achieve this by using DispatchQueue and DispatchGroup, as follows:
Swift 3:
func doEverything(completion: @escaping () -> ()) {
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent, target: .main)
let group = DispatchGroup()
group.enter()
queue.async (group: group) {
print("do alpha")
group.leave()
}
group.enter()
queue.async (group: group) {
print("do beta")
group.leave()
}
group.notify(queue: DispatchQueue.main) {
completion()
}
}
或者,您可以通过这种方式实现它(我觉得它更具可读性):
Or, you can implement it this way (which I find more readable):
func doEverything(completion: @escaping () -> ()) {
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent, target: .main)
let group = DispatchGroup()
queue.async (group: group) {
print("do alpha")
}
queue.async (group: group) {
print("do beta")
}
group.notify(queue: DispatchQueue.main) {
completion()
}
}
请注意,我从 completion
闭包中删除了 success
标志.
Note that I removed the success
flag from the completion
closure.
在这种情况下,do beta"(第二个 queue.async
的执行)不会被执行,直到do alpha"(第一个 queue.async 的执行)
) 完成,那是因为 queue
目标是 .main
.如果你想让两个 queue.async
同时工作,就没有必要创建额外的队列,同一个队列应该做的工作,通过替换:
At this case, "do beta" (the execution of the second queue.async
) won't be executed until "do alpha" (the execution of the first queue.async
) finished, and that's because queue
target is .main
. If you want to let both of queue.async
work concurrently, there is no need to create an extra queue, the same queue should does the work, by replacing:
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent, target: .main)
与:
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent)
现在,系统将控制两个 queue.async
任务应该如何同时工作(显然,group.notify
将在任务拖曳后执行结束).
Now, the system will control over how both of queue.async
tasks should work concurrently (and obviously, group.notify
will be executed after the tow of the tasks finish).
希望这有帮助.
这篇关于当两个其他完成块被调用时调用完成块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!