2

我有三个变量abc。我有三个带有完成块的异步函数来更新这些变量和另外三个只对部分数据进行某些工作的函数。

我确保工作功能等到所有数据都用DispatchGroup.

// The Data
var a: String?
var b: String?
var c: String?

// The Update
let group = DispatchGroup()

group.enter()
updateA() {
    group.leave()
}

group.enter()
updateB() {
    group.leave()
}

group.enter()
updateC() {
    group.leave()
}

group.wait()

// The work
doSomthingWith(a: a, b: b)
doSomethingElseWith(b: b, c: c)
doAnotherThingWith(a: a, c: c)

我希望能够在参数更新后调用每个工作函数,而不是等待一切。这只是一个(显然)简化的版本。可能有更多的变量和函数。

我正在使用斯威夫特。提前谢谢了。

4

1 回答 1

8

要单独使用调度组来实现这一点,您需要 相应地输入和离开三个调度组:

let abGroup = DispatchGroup()
let bcGroup = DispatchGroup()
let acGroup = DispatchGroup()

abGroup.enter()
abGroup.enter()
bcGroup.enter()
bcGroup.enter()
acGroup.enter()
acGroup.enter()

// When a is updated:
abGroup.leave()
acGroup.leave()

// When b is updated:
abGroup.leave()
bcGroup.leave()

// When c is updated:
acGroup.leave()
bcGroup.leave()

然后你可以独立等待每个组的完成

abGroup.notify(queue: .main) {
    // Do something with a and b
}
bcGroup.notify(queue: .main) {
    // Do something with b and c
}
acGroup.notify(queue: .main) {
    // Do something with a and c
}

但是,这不能很好地扩展更多的任务和依赖项。

更好的方法是将Operations 添加到 an OperationQueue中,这允许添加任意依赖项:

let queue = OperationQueue()

let updateA = BlockOperation {
    // ...
}
queue.addOperation(updateA)

let updateB = BlockOperation {
    // ...
}
queue.addOperation(updateB)

let updateC = BlockOperation {
    // ...
}
queue.addOperation(updateC)

let doSomethingWithAandB = BlockOperation {
    // ...
}
doSomethingWithAandB.addDependency(updateA)
doSomethingWithAandB.addDependency(updateB)
queue.addOperation(doSomethingWithAandB)

let doSomethingWithBandC = BlockOperation {
    // ...
}
doSomethingWithBandC.addDependency(updateB)
doSomethingWithBandC.addDependency(updateC)
queue.addOperation(doSomethingWithBandC)

let doSomethingWithAandC = BlockOperation {
    // ...
}
doSomethingWithAandC.addDependency(updateA)
doSomethingWithAandC.addDependency(updateC)
queue.addOperation(doSomethingWithAandC)

对于带有完成处理程序的异步请求,您可以在每个块操作中使用(本地)调度组来等待完成。

这是一个独立的示例:

import Foundation

var a: String?
var b: String?
var c: String?

let queue = OperationQueue()

let updateA = BlockOperation {
    let group = DispatchGroup()
    group.enter()
    DispatchQueue.global().asyncAfter(deadline: .now() + 1.0, execute: {
        a = "A"
        group.leave()
    })
    group.wait()
    print("updateA done")
}
queue.addOperation(updateA)

let updateB = BlockOperation {
    let group = DispatchGroup()
    group.enter()
    DispatchQueue.global().asyncAfter(deadline: .now() + 2.0, execute: {
        b = "B"
        group.leave()
    })
    group.wait()
    print("updateB done")
}
queue.addOperation(updateB)

let updateC = BlockOperation {
    let group = DispatchGroup()
    group.enter()
    DispatchQueue.global().asyncAfter(deadline: .now() + 3.0, execute: {
        c = "C"
        group.leave()
    })
    group.wait()
    print("updateC done")
}
queue.addOperation(updateC)

let doSomethingWithAandB = BlockOperation {
    print("a=", a!, "b=", b!)
}
doSomethingWithAandB.addDependency(updateA)
doSomethingWithAandB.addDependency(updateB)
queue.addOperation(doSomethingWithAandB)

let doSomethingWithAandC = BlockOperation {
    print("a=", a!, "c=", c!)
}
doSomethingWithAandC.addDependency(updateA)
doSomethingWithAandC.addDependency(updateC)
queue.addOperation(doSomethingWithAandC)

let doSomethingWithBandC = BlockOperation {
    print("b=", b!, "c=", c!)
}
doSomethingWithBandC.addDependency(updateB)
doSomethingWithBandC.addDependency(updateC)
queue.addOperation(doSomethingWithBandC)

queue.waitUntilAllOperationsAreFinished()

输出:

更新完成
更新B完成
a= A b= B
更新C完成
a= A c= C
b= B c= C
于 2018-04-30T09:52:57.420 回答