Ios 循环函数中的异步调用。仅在异步完成时返回

Ios 循环函数中的异步调用。仅在异步完成时返回,ios,swift3,closures,alamofire,Ios,Swift3,Closures,Alamofire,我有一个Alamofire调用,在那里我得到一个项目列表,然后我解析它们: class func getList(_ completion:@escaping (Array<Item>) -> Void) { Alamofire.request("http://foo.com", method: .get, parameters: nil, headers: nil) .responseJSON { response in let l

我有一个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>
}

主要问题是,在第一个func中完成之前,我需要所有项的状态,现在当循环已经返回数组时,我会得到一些状态响应。返回带状态的已解析列表的最佳解决方案是什么?

将parse func更改为close,并添加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>)
    }
}

你可以使用一个简单的循环计数器来实现你想要的

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.
                }
        }
    }
}

使用调度组和调度组等待调用completjonlist