Await 0.0.1

Await 0.0.1

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2014年12月
SPM支持SPM

Yasuhiro Inami维护。



Await 0.0.1

  • Yasuhiro Inami

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

如何使用

await

let image = await { downloadLargeImageFromWeb() }

await会为给定的闭包调用dispatch_async并且运行Run Loop直到完成。

await + until

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)

await + timeout

let image = await({ downloadLargeImageFromWeb() }, timeout: 3)  // returns nil if 3 sec has passed

await + finishable closure

您甚至可以在闭包内部使用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中恰当的时间完成。