如何等待结果异步代码

时间:2017-06-15 23:56:27

标签: ios swift

如何等待异步方法的结果?

    let url = URL(string: "https://www.cbr-xml-daily.ru/daily_json.js")
    var dict = NSDictionary()

    let task = URLSession.shared.dataTask(with: url!) { data, response, error in
        guard error == nil else {
            print(error!)
            return
        }
        guard let data = data else {
            print("Data is empty")
            return
        }

        dict = try! JSONSerialization.jsonObject(with: data, options: []) as! NSDictionary
        print("first print\(dict)")
    }

   task.resume()
   print("second \(dict)")

在第一次打印数据中,非空,但在第二次打印时为空

3 个答案:

答案 0 :(得分:0)

这就是你需要完成closure的原因。

    func load(completion: @escaping (NSDictionary) -> ()) {
        let url = URL(string: "https://www.cbr-xml-daily.ru/daily_json.js")
        var dict = NSDictionary()

        let task = URLSession.shared.dataTask(with: url!) { data, response, error in
            guard error == nil else {
                print(error!)
                return
            }
            guard let data = data else {
                print("Data is empty")
                return
            }

            dict = try! JSONSerialization.jsonObject(with: data, options: []) as! NSDictionary
            print("first print\(dict)")

            // Here is when you finish loading data
            completion(dict)
        }

        task.resume()
        print("second \(dict)")
    } 

修改

load(completion: {
    print("My data: \($0)" )
})

答案 1 :(得分:0)

代码不按您怀疑的顺序执行。

您的task.resume()语句启动任务,但该任务可能实际上不会运行或直到明天结束。同时,print(“second(dict)”)立即执行,就在task.resume()语句之后,可能在任务完成之前,期间或之后运行。

使代码等待任务结束的方法是将您想要的代码放在任务响应块中,其中print(“first print(dict)”)语句已经位于该位置。或者,您可以将等待代码放在从该任务响应内部调用的另一个块,方法或函数中。

task.resume()语句之后的任何代码都可以在任务真正启动之前执行。

答案 2 :(得分:0)

假设您下载了一个URL,但就在您执行此操作之前,服务器已崩溃并且只是重新启动,并且您的答案需要50秒才能应用。您的代码应该处理它并且可以轻松完成。

您有丢失的数据。显示数据的代码必须处理它。你说你需要数据 - 不,你不需要。您只是以一种假设存在的方式编写代码,因此更改该假设并在数据不存在时使其工作。当数据稍后到达时,您将更新显示并显示正确的数据。