按顺序快速执行异步任务
我需要在我的应用上执行一些异步的网络任务。假设我有3个资源需要从服务器获取,请拨打A
,B
和C
。假设我在取得B
或C
之前必须首先完成获取资源A
。有时候,我想先取B
,其他时候先取C
。按顺序快速执行异步任务
现在,我只是有一个长链闭合,像这样:
func fetchA() {
AFNetworking.get(completionHandler: {
self.fetchB()
self.fetchC()
})
}
这适用于现在,但明显的限制是我硬编码的执行顺序到完成处理程序fetchA
。现在,说我只想fetchC
fetchB
后,在完成处理程序已经完成,我不得不去改变我的fetchB
实现...
从本质上讲,我想知道是否有一些神奇的方式做是这样的:
let orderedAsync = [fetchA, fetchB, fetchC]
orderedAsync.executeInOrder()
其中fetchA
,fetchB
和fetchC
都是异步的功能,但fetchB
不会执行,直到fetchA
已经完成等等。谢谢!
您可以使用与DispatchGroup.enter()
,DispatchGroup.leave()
和DispatchGroup.modify()
混合的串行DispatchQueue
,这将确保一次只能运行一个执行块。
let serialQueue = DispatchQueue(label: "serialQueue")
let group = DispatchGroup()
group.enter()
serialQueue.async{ //call this whenever you need to add a new work item to your queue
fetchA{
//in the completion handler call
group.leave()
}
}
serialQueue.async{
group.wait()
group.enter()
fetchB{
//in the completion handler call
group.leave()
}
}
serialQueue.async{
group.wait()
group.enter()
fetchC{
group.leave()
}
}
或者,如果你被允许使用第三方库,使用PromiseKit
,它使操控,特别是链接异步方法比什么GCD
提供了比较容易的方式。有关更多信息,请参阅official GitHub页面。 你可以用与在承诺完成处理异步方法,并把它们结合在一起是这样的:
Promise.wrap(fetchA(completion:$0)).then{ valueA->Promise<typeOfValueB> in
return Promise.wrap(fetchB(completion:$0)
}.then{ valueB in
}.catch{ error in
//handle error
}
而且,所有的错误都通过你的承诺传播。
当fetchA/B/C本身是异步的时候,这是行不通的 – dan
包括一个DispatchGroup in该解决方案现在可以正常工作。还提供了PromiseKit作为替代方案。 –
承诺是要走的路! –
不相关,但您可能会考虑使用Alamofire而不是AFNetworking。它是由同一作者撰写的,但是是一个Swift解决方案。但是你仍然需要做一些事情来处理异步任务,PromiseKit,一些异步操作子类来封装请求,或者类似的东西。 – Rob
如果你确实留在AFNetworking中,我为它做了一个'NSOperation'包装:https://github.com/robertmryan/AFHTTPSessionOperation – Rob