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()
})
}
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()
where fetchA
, fetchB
, and fetchC
are all async functions, but fetchB
won't execute until fetchA
has finished and so on. Thanks!
You can use a serial DispatchQueue
mixed with a DispatchGroup
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()
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With