完成很快就会被调用 [英] Completion gets called soon
问题描述
我有以下功能.我正在尝试将 allItems 数组传递到 requestItems
的完成块中,但我遇到了崩溃,因为它说它为零.我删除了完成以检查 item
是否具有值并且确实如此.
I have the following functions. I'm trying to pass allItems array into the completion block of requestItems
, but I get a crash as it says it's nil. I removed the completion to check that item
has a value and it does.
这意味着完成在 for 循环之前执行.
That means that the completion executes before the for loop.
还有其他方法吗?类似于 Javascript 中的 Promises,它会在 for 循环完成时执行完成.
Is there another approach for this? Something like Promises in Javascript that will execute the completion when the for loop has finished.
func requestItems(_ data: [String: Any], completion: (Bool, [Item]) -> Void) {
var allItems = [Item]()
for i in data["all"] {
Routes.instance.getRequest(requestType: "items", params: nil, id: someId, completion: { item in
var it = Item(item["name"] as! String)
allItems.append(it)
})
}
completion(true, allItems)
}
func getRoutes(requestType: String, parameters: [String: Any]?, id: String, completion: @escaping ([[String:Any]]) -> Void) {
DispatchQueue.main.async {
if id == "" {
self.url = "\(URL_BASE)/\(requestType)"
} else {
self.url = "\(URL_BASE)/\(requestType)/\(id)"
}
Alamofire.request(self.url, method: .get, parameters: parameters, encoding: JSONEncoding.default, headers: self.headers).responseJSON { response in
guard response.result.error == nil else {
print(response.result.error!)
return
}
switch response.result {
case .success(let JSON):
let response = [JSON] as! NSArray
for item in response {
if let data = item as? [String: Any] {
print(data)
}
}
completion(response as! [[String : Any]])
case .failure(let error):
print("Request failed with error: \(error)")
}
}
}
}
完成处理程序执行太快,返回一个 nil 项
The completion handler executes too soon, returning a nil item
推荐答案
你需要 DispatchGroup
在异步循环完成时得到通知,例如:
You need DispatchGroup
to get notified when the asynchronous loop is finished for example:
func requestItems(_ data: [String: Any], completion: (Bool, [Item]) -> Void) {
var allItems = [Item]()
let group = DispatchGroup()
for i in data["all"] {
group.enter()
Routes.instance.getRequest(requestType: "items", params: nil, id: someId, completion: { item in
let it = Item(item["name"] as! String)
allItems.append(it)
group.leave()
})
}
group.notify(queue: DispatchQueue.main) {
completion(true, allItems)
}
}
这篇关于完成很快就会被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!