简体   繁体   English

如何等待结果异步代码

[英]How await result async code

How to await result from async method? 如何等待异步方法的结果?

    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)")

In first print data not empty but in second print is empty 在第一个打印数据中,非空但在第二个打印中是空的

That's why you need completion 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)")
    } 

EDIT 编辑

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

The code does not execute in the order you suspect. 代码不按您怀疑的顺序执行。

Your task.resume() statement starts the task, but the task might not actually run or finish till tomorrow. 您的task.resume()语句启动任务,但该任务可能实际上不会运行或直到明天结束。 Meanwhile, print("second (dict)") executes right away, today, right after the task.resume() statement, perhaps running any of before, during, or after the task completion. 同时,print(“second(dict)”)立即在task.resume()语句之后立即执行,可能在任务完成之前,期间或之后运行。

The way to have code await the end of your task is to put that code that you want to await inside the task response block, where your print("first print(dict)") statement is already located. 让代码等待任务结束的方法是将您想要的代码放在任务响应块中,其中print(“first print(dict)”)语句已经位于该位置。 Or you can put the waiting code in another block, method, or function, called from inside that task response. 或者,您可以将等待代码放在从该任务响应内部调用的另一个块,方法或函数中。

Any code after the task.resume() statement may execute way before the task even really starts. task.resume()语句之后的任何代码都可以在任务真正启动之前执行。

Assume you download a URL, but just before you do that the server has crashed and was just re-booting, and it takes 50 seconds for your answer to apply. 假设您下载了一个URL,但就在您执行此操作之前,服务器已崩溃且只是重新启动,并且您的答案需要50秒才能应用。 Your code should handle that and can do it easily. 您的代码应该处理它并且可以轻松完成。

You have data that is missing. 您有丢失的数据。 Your code displaying data just has to handle that. 显示数据的代码必须处理它。 You say you need the data - no, you don't. 你说你需要数据 - 不,你不需要。 You just have written your code in a way that assumes it's there, so change that assumption and make it work when the data isn't there. 您只是以一种假设存在的方式编写代码,因此更改该假设并在数据不存在时使其工作。 And when the data arrives later, you update the display and show the correct data. 当数据稍后到达时,您将更新显示并显示正确的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM