快速执行异步任务 [英] Swift execute asynchronous tasks in order
问题描述
我需要在应用程序上执行一些异步的网络任务。假设我有3种资源需要从服务器获取,分别称为 A
, B
和 C
。假设我必须先完成获取资源 A
,然后再获取 B
或 C
。有时,我想先获取 B
,而其他时候首先获取 C
。
I have a few asynchronous, network tasks that I need to perform on my app. Let's say I have 3 resources that I need to fetch from a server, call them A
, B
, and C
. Let's say I have to finish fetching resource A
first before fetching either B
or C
. Sometimes, I'd want to fetch B
first, other times C
first.
现在,我只是有一个像这样的长链闭包:
Right now, I just have a long-chained closure like so:
func fetchA() {
AFNetworking.get(completionHandler: {
self.fetchB()
self.fetchC()
})
}
目前可以使用,但明显的局限性是我已将执行顺序硬编码到的完成处理程序中fetchA
。现在,假设我只想在该完成处理程序中的 fetchB
完成后, fetchC
我的 fetchB
...
This works for now, but the obvious limitation is I've hard-coded the order of execution into the completion handler of fetchA
. Now, say I want to only fetchC
after fetchB
has finished in that completion handler, I'd have to go change my implementation for fetchB
...
的实现本质上,我想知道是否有某种神奇的方法像这样的
Essentially, I'd like to know if there's some magic way to do something like:
let orderedAsync = [fetchA, fetchB, fetchC]
orderedAsync.executeInOrder()
其中 fetchA
, fetchB
和 fetchC
都是异步函数,但是 fetchB
直到<$ c $才会执行c> fetchA 已完成,依此类推。谢谢!
where fetchA
, fetchB
, and fetchC
are all async functions, but fetchB
won't execute until fetchA
has finished and so on. Thanks!
推荐答案
您可以将串行 DispatchQueue
与<$混合使用c $ c> DispatchGroup.enter(), DispatchGroup.leave()
和 DispatchGroup.modify()
可以确保一次只运行一个执行块。
You can use a serial DispatchQueue
mixed with DispatchGroup.enter()
, DispatchGroup.leave()
and DispatchGroup.modify()
which will ensure that only one execution block will run at a time.
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()
}
}
或者如果您被允许使用第3个方库,使用 PromiseKit
,它使处理方法(尤其是链接异步方法)比 GCD
提供的任何方法都容易。有关更多信息,请参见官方GitHub 页面。
您可以将带有完成处理程序的异步方法包装在Promise中,并将它们链接在一起,如下所示:
Or if you are allowed to use a 3rd party library, use PromiseKit
, it makes handling and especially chaining async methods way easier than anything GCD
provides. See the official GitHub page for more info.
You can wrap an async method with a completion handler in a Promise and chain them together like this:
Promise.wrap(fetchA(completion:$0)).then{ valueA->Promise<typeOfValueB> in
return Promise.wrap(fetchB(completion:$0)
}.then{ valueB in
}.catch{ error in
//handle error
}
此外,所有错误都通过您的承诺传播。
Also, all errors are propagated through your promises.
这篇关于快速执行异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!