处理多个完成处理程序
Dealing with multiple completion handlers
我正在尝试为数组中的每个元素协调多个完成处理程序。
代码本质上是这样的:
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)
}
因此数组中的每个元素都通过具有完成处理程序的服务发送,所有结果都存储在一个数组中。一旦所有这些处理程序完成,我希望执行一些代码。
我试图用 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)
}
}
但是 print 调用仍然首先执行,空 Dictionary
如果我理解你正在尝试正确地做什么,你可能想使用 DispatchGroup
这是一个例子:
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")
}
这将打印如下内容:
b
c
a
// ^ in some order
- done
首先,请注意您的 service.request(...)
是在异步模式下处理的。另一个问题是您想在该循环中完成所有服务请求。
我的建议是创建带有完成处理程序的函数,并在每个完成的循环上添加一个计数器。您的功能将类似于以下内容。
var results = [String:Int]()
func requestData(for identifiers: [String], callback:@escaping (Bool) -> Void)
{
var counter = 0
var maxItem = identifiers.count
identifiers.forEach
{ identifier in
service.request(identifier, completion: { (result) in
result[identifier] = result
counter += 1
if counter == maxItem {
callback(true) // update completion handler to say all loops request are done
}
// if not, continue the other request
})
}
}
这就是您的代码的另一部分调用函数并等待回调的方式
requestData(for identifiers:yourArrays) { (complete) in
if complete {
print(results)
}
}
如果发生错误,请不要忘记管理。
我正在尝试为数组中的每个元素协调多个完成处理程序。
代码本质上是这样的:
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)
}
因此数组中的每个元素都通过具有完成处理程序的服务发送,所有结果都存储在一个数组中。一旦所有这些处理程序完成,我希望执行一些代码。
我试图用 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)
}
}
但是 print 调用仍然首先执行,空 Dictionary
如果我理解你正在尝试正确地做什么,你可能想使用 DispatchGroup
这是一个例子:
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")
}
这将打印如下内容:
b
c
a
// ^ in some order
- done
首先,请注意您的 service.request(...)
是在异步模式下处理的。另一个问题是您想在该循环中完成所有服务请求。
我的建议是创建带有完成处理程序的函数,并在每个完成的循环上添加一个计数器。您的功能将类似于以下内容。
var results = [String:Int]()
func requestData(for identifiers: [String], callback:@escaping (Bool) -> Void)
{
var counter = 0
var maxItem = identifiers.count
identifiers.forEach
{ identifier in
service.request(identifier, completion: { (result) in
result[identifier] = result
counter += 1
if counter == maxItem {
callback(true) // update completion handler to say all loops request are done
}
// if not, continue the other request
})
}
}
这就是您的代码的另一部分调用函数并等待回调的方式
requestData(for identifiers:yourArrays) { (complete) in
if complete {
print(results)
}
}
如果发生错误,请不要忘记管理。