完成很快就会被调用 [英] Completion gets called soon

查看:34
本文介绍了完成很快就会被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下功能.我正在尝试将 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆