如何等待异步方法的结果?
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)")
在第一次打印数据中,非空,但在第二次打印时为空
答案 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秒才能应用。您的代码应该处理它并且可以轻松完成。
您有丢失的数据。显示数据的代码必须处理它。你说你需要数据 - 不,你不需要。您只是以一种假设存在的方式编写代码,因此更改该假设并在数据不存在时使其工作。当数据稍后到达时,您将更新显示并显示正确的数据。