循环函数中的异步调用。仅在异步完成时返回
Posted
技术标签:
【中文标题】循环函数中的异步调用。仅在异步完成时返回【英文标题】:Async call in loop func. Return only when async finished 【发布时间】:2016-12-08 10:43:12 【问题描述】:我有一个 Alamofire 调用,我在其中获取项目列表,然后解析它们:
class func getList(_ completion:@escaping (Array<Item>) -> Void)
Alamofire.request("http://foo.com", method: .get, parameters: nil, headers: nil)
.responseJSON response in
let list = parseList(response as! NSArray)
completion(list)
当我解析列表时,我需要再次调用以获取项目的状态:
class func parseList(_ responseArray: NSArray) -> Array<Item>
let list = NSMutableArray()
for itemDic in responseArray
let item = Item()
item.id = itemDic.value(forKey: "Id") as? Int
item.name = itemDic.value(forKey: "Name") as? Int
Alamofire.request("http://bar.com", method: .get, parameters: nil, headers: nil)
.responseJSON response in
item.status = response as? String
list.add(item)
return list as NSArray as! Array<Item>
主要问题是我需要在第一个函数中完成之前获得所有项目状态,现在当循环已经返回数组时我会得到一些状态响应。返回带有状态的解析列表的最佳解决方案是什么?
【问题讨论】:
使用 dispatch group 和 dispatch_group_wait 调用completjon(list)
【参考方案1】:
将解析函数更改为闭包并添加 DispatchGroup 直到设置所有状态。
第一个函数:
class func getList(_ completion:@escaping (Array<Item>) -> Void)
Alamofire.request("http://foo.com", method: .get, parameters: nil, headers: nil)
.responseJSON response in
self.parseList(response as! NSArray, completion: (list) in
completion(list)
)
第二个功能:
class func parseList(_ responseArray: NSArray, completion:@escaping(Array<Item>) - Void)
let dispatch = DispatchGroup()
let list = NSMutableArray()
for itemDic in responseArray
let item = Item()
item.id = itemDic.value(forKey: "Id") as? Int
item.name = itemDic.value(forKey: "Name") as? Int
dispatch.enter()
Alamofire.request("http://bar.com", method: .get, parameters: nil, headers: nil)
.responseJSON response in
item.status = response as? String
dispatch.leave()
list.add(item)
dispatchGroup.notify(queue: DispatchQueue.main)
completion(list as NSArray as! Array<Item>)
【讨论】:
【参考方案2】:你可以使用一个简单的循环计数器来实现你想要的......
class func getList(_ completion:@escaping (Array<Item>) -> Void)
Alamofire.request("http://foo.com", method: .get, parameters: nil, headers: nil)
.responseJSON response in
let list = parseList(response as! NSArray)
completion(list)
从这里我修改了你的一些代码...我声明了一个计数器来确定何时抛出带有状态项的完整列表的回调。
class func parseList(_ responseArray: NSArray, _ completion: @escaping (Array<Any>) -> Void)
let list = NSMutableArray()
let counter: Int = 0 // counter
for itemDic in responseArray
let item = Item()
item.id = itemDic.value(forKey: "Id") as? Int
item.name = itemDic.value(forKey: "Name") as? Int
Alamofire.request("http://bar.com", method: .get, parameters: nil, headers: nil)
.responseJSON response in
item.status = response as? String
list.add(item) // when the alamofire return the call we set the status then add it to our list..
counter += 1 // then increment our counter
// here ... we verify if the counter matches the total count of the item we need need to fetch
if responseArray.count == counter
completion(list) // if it matches the total count then we will fire the callback with the list of the item with statuses.
【讨论】:
以上是关于循环函数中的异步调用。仅在异步完成时返回的主要内容,如果未能解决你的问题,请参考以下文章