C#的Await的Swift端口,使用Cocoa的Run Loop机制。
(对于单元测试很有用,但需要特别注意应用程序使用)
Await
showProgressHUD("Start!") // displays AFTER download finished (you know why)
let image = downloadLargeImageFromWeb() // OMG downloading from main-thread!!!
showProgressHUD("Finished!") // displays after download finished
showProgressHUD("Start!") // main-thread
// OK let's use dispatch_async then...
dispatch_async(globalQueue) {
image = downloadLargeImageFromWeb() // background-thread
dispatch_async(dispatch_get_main_queue()) {
showProgressHUD("Finished!") // main-thread
// want more nested blocks here?
}
}
Await
showProgressHUD("Start!")
let image = await { downloadLargeImageFromWeb() }
// because of await's running Run Loop, "Start!" will be displayed immediately here
showProgressHUD("Finished!") // displays after download finished
let image = await { downloadLargeImageFromWeb() }
await
会为给定的闭包调用dispatch_async
并且运行Run Loop直到完成。
var shouldStop = false
var container: SomeContainer
let result = await({
container.data = nil
dispatch_async(globalQueue) {
container.data = downloadData()
shouldStop = true
}
return container.data
}, until: { shouldStop })
使用until: () -> Bool
来手动调整Run Loop的运行时间。这在与像Promise这样的异步编程monads结合使用时特别有用。
查看PromiseKit示例
import PromiseKit
var promise = Promise<NSData> { (fulfiller, rejecter) in ... }
...
let result = await({ promise.value }, until: { !promise.pending })
// or, let result = await(promise)
let image = await({ downloadLargeImageFromWeb() }, timeout: 3) // returns nil if 3 sec has passed
您甚至可以在闭包内部使用finish()
或finish(returnValue)
来手动停止Run Loop的运行,而不是使用await(_:until:)
。
let data = await { finish in
dispatch_async(queue) {
let d = downloadData()
finish(d) // pass result data
}
}
var data: NSData?
await { finish in
dispatch_async(queue) {
let d = downloadData()
data = d
finish() // no return
}
}
对于应用程序使用,您必须将await
调用用async
包裹如下
async {
var image = await { downloadLargeImageFromWeb() }
image = await { filterImage(image) }
}
这是为了确保await
不会阻塞dispatch_get_main_queue()
,这通常会导致UIKit不会响应用户的触摸。
由于嵌套Run Loop的运行,await(_:timeout:)
和嵌套的await
可能不会在async
中恰当的时间完成。