I'm trying to coordinate several completion handlers for each element in an array.
The code is essentially this:
var results = [String:Int]()
func requestData(for identifiers: [String])
{
identifiers.forEach
{ identifier in
service.request(identifier, completion: { (result) in
result[identifier] = result
})
}
// Execute after all the completion handlers finish
print(result)
}
So each element in the Array is sent through a service with a completion handler, and all the results are stored in an array. Once all of these handlers complete, I wish to execute some code.
I attempted to do this with DispatchQueue
var results = [String:Int]()
func requestData(for identifiers: [String])
{
let queue = DispatchQueue.init(label: "queue")
identifiers.forEach
{ identifier in
service.request(identifier, completion: { (result) in
queue.sync
{
result[identifier] = result
}
})
}
// Execute after all the completion handlers finish
queue.sync
{
print(result)
}
}
but the print call is still being executed first, with an empty Dictionary
A completion handler in Swift is a function that calls back when a task completes. This is why it is also called a callback function. A callback function is passed as an argument into another function. When this function completes running a task, it executes the callback function.
As an example, many functions that start an asynchronous operation take a closure argument as a completion handler. The function returns after it starts the operation, but the closure isn't called until the operation is completed—the closure needs to escape, to be called later.
Make a Completion handler : Create a completion handler closure and than pass it to function. Here we create an completion handler closure which type is () → Void . Now We will create a function which can take this closure .. Here we create a function which take a parameter of type () →Void .
If I understand what are you are trying to do correctly, you probably want to use a DispatchGroup
Here is an example:
let group = DispatchGroup()
var letters = ["a", "b", "c"]
for letter in letters {
group.enter()
Server.doSomething(completion: { [weak self] (result) in
print("Letter is: \(letter)")
group.leave()
})
}
group.notify(queue: .main) {
print("- done")
}
This will print something like:
b
c
a
// ^ in some order
- done
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