我是异步方面的新手,我正在尝试实现对函数的简单异步调用。
import UIKit
func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) {
print("start async")
sleep(5) // to simulate long work
let result: Double = 123.456
completionHandler(result)
}
print("A")
doAsyncStuff() { result in
print(result)
}
print("B")
执行时,我得到
A
start async
123.456
B
由于func是异步调用的,所以我希望得到
A
start async
B
123.456
我哪里出错了? 非常感谢
答案 0 :(得分:3)
问题在于您正在调用sleep
,这是一个同步阻塞函数,因此您将主线程阻塞了5秒钟,并且在此期间无法执行其他任何操作。您应该使用DispatchQueue.asyncAfter
测试简单的异步调用。
您还可以知道您的函数不是异步的,因为没有收到未将闭包标记为@escaping
的编译器错误,您需要对异步完成处理程序执行此操作。
func doAsyncStuff(completionHandler: @escaping (_ result: Double) -> Void) {
print("start async")
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
completionHandler(123.456)
}
}
答案 1 :(得分:2)
您的函数不是异步的。每行代码都正在同步运行(即在执行之前等待该行完成)。因此sleep(5)在函数中间暂停执行,直到函数返回后才调用print(“ B”)。
您可以使用Grand Central Dispatch (GCD)在不同线程上异步运行代码。这是一个示例:
import UIKit
func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) {
DispatchQueue.global(qos: .background).async { [weak self] in
print("start async")
sleep(5)
let result: Double = 123.456
completionHandler(result)
}
}
print("A")
doAsyncStuff() { result in
print(result) // This is your completion handler code
}
print("B")
答案 2 :(得分:1)
当心,您正在同一线程上调用函数,因此它将是同步的!
要以异步方式调用它,请创建一个后台线程/任务,然后从该后台线程调用您的函数。一种方法:
print("A")
DispatchQueue.global(qos: .background).async {
//this is a background thread, do in it your async stuff
doAsyncStuff() { result in
print(result)
}
}
print("B")
答案 3 :(得分:1)
使用 DispatchQueue.main.asyncAfter 快速进行异步调用。 因此您的代码应该看起来像..
func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) {
print("start async")
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
// your code goes from here
let result: Double = 123.456
completionHandler(result)
}
}