我循环遍历表的行,对于每个行我都在做几个异步调用,比如从API获取数据,复制文件,运行shell脚本......如何等待结果直到下一个。
我也是Swift的新手,不知道这是否是处理一组异步任务的最佳方法。在这种情况下我应该使用并发吗?
tableView.selectedRowIndexes.forEach { row in
myData.fetch(url: urlList[row]) { res in
self.anotherAsyncCall(res) { data in
//continue to deal with next row now
}
}
}
答案 0 :(得分:1)
如果您真的想按顺序执行此操作,最简单的方法是递归执行您的任务,实际调用前一个任务的完成处理程序中的下一个任务:
processNext(in: tableView.selectedRowIndexes) {
// do something when they're all done
}
其中:
func processNext(in rows: [Int], completion: @escaping () -> Void) {
guard let row = rows.first else {
completion()
return
}
myData.fetch(url: urlList[row]) { res in
self.anotherAsyncCall(res) { data in
//continue to deal with next row now
self.processNext(in: Array(rows.dropFirst()), completion: completion)
}
}
}
但我同意GoodSp33d的另一种方法是将这个异步过程包装在一个自定义的异步Operation
子类中。
但这引出了为什么要按顺序执行这些操作的问题。由于每个请求的固有网络延迟,您将支付显着的性能损失。因此,另一种方法是让它们同时运行,并使用调度组来了解它们何时完成:
let group = DispatchGroup()
tableView.selectedRowIndexes.forEach { row in
group.enter()
myData.fetch(url: urlList[row]) { res in
self.anotherAsyncCall(res) { data in
//continue to deal with next row now
group.leave()
}
}
}
group.notify(queue: .main) {
// do something when they're all done
}
您是否可以同时(或在何种程度上)运行这些是您在各种异步方法中所做的功能。但我建议你同时努力使这项工作同时进行,因为性能可能要好得多。
答案 1 :(得分:0)
如果您使用的是某个promise库,只需使用all
函数。
Here是关于promise.all()
的文档 PromiseKit使用when
代替,
您可以阅读faq和tutorial about when了解更多信息。
如果你想在没有任何promise库的情况下这样做,这里是伪代码:
var results = []
rows.forEach {row in
fetch(row) {res in
results.push(res)
if(results.length == rows.length) {
// do something using the results here
}
}
}