【发布时间】:2018-10-06 16:53:30
【问题描述】:
我有 a、b、c、d、e 耗时的任务函数和完成处理程序。
它们之间有约束:
- b 和 c 都等待 a 完成
- 最后一个任务 e 等待 b & c & d 完成
如果没有任务d,我可以像这样快速编写代码(尚未测试)
let group = DispatchGroup()
group.enter()
a() { group.leave() }
group.wait()
group.enter()
b() { group.leave() }
group.enter()
c() { group.leave() }
group.notify(queue: .main) {
e()
}
如何在不等待a完成的情况下添加任务d?
编辑于 4/30 10:00 (+8)
代码不同说
最简单的方法是使下载函数同步,并在其文档中添加一条警告,即永远不要从主线程调用它。
所以我根据它做了一个版本。这种方式无法处理来自并发调用的返回值。但它看起来真的很像 async/await。所以我现在很满意。谢谢各位。
async/await like 部分是
myQueue.async {
downloadSync("A")
downloadSync("B", isConcurrent: true)
downloadSync("C", isConcurrent: true)
downloadSync("D", 4, isConcurrent: true)
waitConcurrentJobs()
downloadSync("E")
}
完整的代码如下。
let myGroup = DispatchGroup()
let myQueue = DispatchQueue(label: "for Sync/Blocking version of async functions")
func waitConcurrentJobs() {
myGroup.wait()
}
// original function (async version, no source code)
func download(_ something: String, _ seconds: UInt32 = 1, completionHandler: @escaping ()->Void = {}) {
print("Downloading \(something)")
DispatchQueue.global().async {
sleep(seconds)
print("\(something) is downloaded")
completionHandler()
}
}
// wrapped function (synced version)
// Warning:
// It blocks current thead !!!
// Do not call it on main thread
func downloadSync(
_ something: String,
_ seconds: UInt32 = 1,
isConcurrent: Bool = false
){
myGroup.enter()
download(something, seconds) { myGroup.leave() }
if !isConcurrent {
myGroup.wait()
}
}
// Now it really looks like ES8 async/await
myQueue.async {
downloadSync("A")
downloadSync("B", isConcurrent: true)
downloadSync("C", isConcurrent: true)
downloadSync("D", 4, isConcurrent: true)
waitConcurrentJobs()
downloadSync("E")
}
结果
【问题讨论】:
-
对不起,我只想问一下,为什么不使用操作和依赖项。操作确实存在于 GCD 之上,并且依赖项可以完全满足您的要求。
-
因为我从来没有听说过他们。我正在开发我的第一个 Swift 应用程序(从 react native 切换)谢谢~我会用谷歌搜索它们。 :-)
-
Swift 中的操作是 Apple 的 Foundation API 的一部分。它曾经是 NSOperation,但前段时间已重命名为 Operation。 developer.apple.com/documentation/foundation/operation
-
如果您必须将上一个任务的结果传递给下一个任务,使用
Operation将变得非常复杂和麻烦(== 容易出错),因为您需要同步数据传输(例如再次使用调度队列)。
标签: swift asynchronous grand-central-dispatch completionhandler