Async

简介:

Async

https://github.com/duemunk/Async

 

Syntactic sugar in Swift for asynchronous dispatches in Grand Central Dispatch (GCD)

这是一个Swift中GCD的语法糖库。

 

Async sugar looks like this:

Async使用起来就像这样子:

Async.background {
    println("This is run on the background queue")
}.main {
    println("This is run on the main queue, after the previous block") }

Instead of the familiar syntax for GCD:

替换了下面的这种显示方式:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {
    println("This is run on the background queue")

    dispatch_async(dispatch_get_main_queue(), {
        println("This is run on the main queue, after the previous block") }) })

Install

pod 'Async', :git => 'https://github.com/duemunk/Async.git'

 

Benefits

  1. Less verbose code 更少的冗余代码
  2. Less code indentation 更少的缩进风

 

Things you can do

Supports the modern queue classes:

支持常用的queue类:

Async.main {}
Async.userInteractive {}
Async.userInitiated {}
Async.utility {}
Async.background {}

Chain as many blocks as you want:

你可以将不同的block链接起来使用:

Async.userInitiated {
    // 1
}.main {
    // 2
}.background {
    // 3 }.main { // 4 }

Store reference for later chaining:

也可以分开使用:

let backgroundBlock = Async.background {
    println("This is run on the background queue") } // Run other code here... // Chain to reference backgroundBlock.main { println("This is run on the \(qos_class_self().description) (expected \(qos_class_main().description)), after the previous block") }

Custom queues:

自定义queue:

let customQueue = dispatch_queue_create("CustomQueueLabel", DISPATCH_QUEUE_CONCURRENT)
let otherCustomQueue = dispatch_queue_create("OtherCustomQueueLabel", DISPATCH_QUEUE_CONCURRENT) Async.customQueue(customQueue) { println("Custom queue") }.customQueue(otherCustomQueue) { println("Other custom queue") }

Dispatch block after delay:

延时执行:

let seconds = 0.5
Async.main(after: seconds) { println("Is called after 0.5 seconds") }.background(after: 0.4) { println("At least 0.4 seconds after previous block, and 0.9 after Async code is called") }

Cancel blocks that aren't already dispatched:

取消没有启动的线程:

// Cancel blocks not yet dispatched
let block1 = Async.background {
    // Heavy work
    for i in 0...1000 { println("A \(i)") } } let block2 = block1.background { println("B – shouldn't be reached, since cancelled") } Async.main { // Cancel async to allow block1 to begin block1.cancel() // First block is _not_ cancelled block2.cancel() // Second block _is_ cancelled }

Wait for block to finish – an ease way to continue on current queue after background task:

等待一个block运行结束:

let block = Async.background {
    // Do stuff
}

// Do other stuff

block.wait()

 

How does it work

The way it work is by using the new notification API for GCD introduced in OS X 10.10 and iOS 8. Each chaining block is called when the previous queue has finished.

本库使用了 iOS 8 提供的通知 API 来完成相关功能,每一个block都会在上一个block执行完了之后继续执行:

let previousBlock = {}
let chainingBlock = {}
let dispatchQueueForChainingBlock = ... // Use the GCD API to extend the blocks let _previousBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, previousBlock) let _chainingBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, chainingBlock) // Use the GCD API to call back when finishing the "previous" block dispatch_block_notify(_previousBlock, dispatchQueueForChainingBlock, _chainingBlock)

The syntax part of the chaining works by having class methods on the Async object e.g. Async.main {} which returns a struct. The struct has matching methods e.g. theStruct.main {}.

 

Known bugs

Modern GCD queues don't work as expected in the iOS Simulator. See issues 1322.

 

Known improvements

The dispatch_block_t can't be extended. Workaround used: Wrap dispatch_block_t in a struct that takes the block as a property.

 

Bonus stuff

There is also a wrapper for dispatch_apply() for quick parallelisation of a for loop.

Apply.background(100) { i in
    // Do stuff e.g. println(i)
}

Note that this function returns after the block has been run all 100 times i.e. it is not asynchronous. For asynchronous behaviour, wrap it in a an Async block like Async.main{ Apply.background(100) { ... } }.

 

 

 

目录
相关文章
|
6月前
|
前端开发 JavaScript
什么是 async、await ?
什么是 async、await ?
|
JSON 前端开发 JavaScript
async/await的应用
async/await的应用
62 0
|
前端开发 JavaScript
|
17天前
|
JSON 前端开发 JavaScript
浅谈JavaScript中的Promise、Async和Await
【10月更文挑战第30天】Promise、Async和Await是JavaScript中强大的异步编程工具,它们各自具有独特的优势和适用场景,开发者可以根据具体的项目需求和代码风格选择合适的方式来处理异步操作,从而编写出更加高效、可读和易于维护的JavaScript代码。
22 1
|
6月前
|
前端开发 JavaScript 开发者
阿珊带你深入理解 async/await 函数
阿珊带你深入理解 async/await 函数
|
6月前
|
前端开发 JavaScript
async/await
async/await
36 0
|
6月前
|
JSON 前端开发 JavaScript
什么是async和await?
什么是async和await?
54 0
|
6月前
|
JSON 前端开发 JavaScript
|
6月前
|
前端开发 JavaScript
|
前端开发 API
Async/Await 在何时该使用,何时不使用
使用 async/await 是在处理异步操作时的一种更简洁、易读的方式,它基于 Promise,并且可以使异步代码看起来像同步代码一样编写。然而,并不是所有情况下都需要使用 async/await。
205 0