当两个其他完成块被调用时调用完成块 [英] Call completion block when two other completion blocks have been called

查看:23
本文介绍了当两个其他完成块被调用时调用完成块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数 doEverything 需要一个完成块.它调用另外两个函数,doAlphadoBeta,它们都有完成块.这两个函数应该异步运行.我想在其他两个函数都调用了它们的完成块之后调用 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)
}

doAlphadoBeta 应该同时运行,一旦它们都完成,完成块应该用 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) 是您在此处尝试执行的操作的不错选择,您可以使用 DispatchQueueDispatchGroup,如下:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆