AsyncTask:类似 async function 的 Swift 异步编程库

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看481 回复回复2 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 481|回复: 2
收起左侧

AsyncTask:类似 async function 的 Swift 异步编程库

[复制链接]
SwiftRobot 发表于 2016-6-21 14:42:59 | 显示全部楼层 |阅读模式
快来登录
获取最新的苹果动态资讯
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码

An asynchronous programming library for Swift

AsyncTask:类似 async function 的 Swift 异步编程库

AsyncTask:类似 async function 的 Swift 异步编程库 - 敏捷大拇指 - AsyncTask:类似 async function 的 Swift 异步编程库





Features

AsyncTask is much more than Future and Promise.
  • It is composable, allowing you to build complex workflow.
  • It supports native error handling with do-catch and try.
  • It is protocol oriented; so you can turn any object into a Task.


Without AsyncTask:

[Swift] 纯文本查看 复制代码
// get a global concurrent queue
let queue = dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)
// submit a task to the queue for background execution
dispatch_async(queue) {
    let enhancedImage = self.applyImageFilter(image) // expensive operation taking a few seconds
    // update UI on the main queue
    dispatch_async(dispatch_get_main_queue()) {
        self.imageView.image = enhancedImage
        UIView.animateWithDuration(0.3, animations: {
            self.imageView.alpha = 1
        }) { completed in
            // add code to happen next here
        }
    }
}


With AsyncTask:

[Swift] 纯文本查看 复制代码
Task {
    let enhancedImage = self.applyImageFilter(image)
    Task {self.imageView.image = enhancedImage}.async(.Main)
    let completed = UIView.animateWithDurationAsync(0.3) { self.label.alpha = 1 }.await(.Main)
    // add code to happen next here
}.async()


It even allows you to extend existing types:

[Swift] 纯文本查看 复制代码
let (data, response) = try! NSURL(string: "www.google.com")!.await()





Installation

AsyncTask is available through CocoaPods. To install it, simply add the following line to your Podfile:

[Swift] 纯文本查看 复制代码
pod "AsyncTask"





Tutorial

Async Programming in Swift with AsyncTask




Usage

In AsyncTask, a Task represents the eventual result of an asynchronous operation, as do Future and Promise in other libraries. It can wrap both synchronous and asynchronous APIs. To create a Task, initialize it with a closure. To make it reusable, write functions that return a task.

[Swift] 纯文本查看 复制代码
// synchronous API
func encrypt(message: String) -> Task<String> {
    return Task {
        encrypt(message)
    }
}
// asynchronous API
func get(URL: NSURL) -> Task<(NSData?, NSURLResponse?, NSError?)> {
    return Task {completionHandler in
        NSURLSession().dataTaskWithURL(URL, completionHandler: completionHandler).resume()
    }
}


To get the result of a Task, use async or await. async is just like dispatch_async, and you can supply a completion handler. await, on the contrary, blocks the current thread and waits for the task to finish.

[Swift] 纯文本查看 复制代码
// async
encrypt(message).async { ciphertext in /* do somthing */ }
get(URL).async {(data, response, error) in /* do somthing */ }

// await
let ciphertext = encrypt(message).await()
let (data, response, error) = get(URL).await()





Composing Tasks

You can use multiple await expressions to ensure that each statement completes before executing the next statement:

[Swift] 纯文本查看 复制代码
Task {
    print(“downloading image”)
    var image = UIImage(data: downloadImage.await())!
    updateImageView(image).await(.Main)
    print(“processing image”)
    image = processImage(image).await()
    updateImageView(image).await(.Main)
    print(“finished”)
}.async()


You can also call awaitFirst and awaitAll on a collection of tasks to execute them in parallel:

[Swift] 纯文本查看 复制代码
let replicatedURLs = ["https://web1.swift.org", "https://web2.swift.org"]
let first = replicatedURLs.map(get).awaitFirst()

let messages = ["1", "2", "3"]
let all = messages.map(encrypt).awaitAll()





Handling Errors

Swift provide first-class support for error handling. In AsyncTask, a ThrowableTask takes a throwing closure and propagates the error.

[Swift] 纯文本查看 复制代码
func load(path: String) -> ThrowableTask<NSData> {
    return ThrowableTask {
        switch path {
        case "profile.png":
            return NSData()
        case "index.html":
            return NSData()
        default:
            throw Error.NotFound
        }
    }
}

expect{try load("profile.png").await()}.notTo(throwError())
expect{try load("index.html").await()}.notTo(throwError())
expect{try load("random.txt").await()}.to(throwError())





Extending Tasks

AsyncTask is protocol oriented; it defines TaskType and ThrowableTaskType and provides the default implementation of async and await using protocol extension. In other words, these protocols are easy to implement, and you can await on any object that confronts to them. Being able to extend tasks powerful because it allows tasks to encapsulate states and behaviors.

In the following example, by extending NSURL to be TaskType, we make data fetching a part of the NSURL class. To confront to the TaskType protocol, just specify an action and the return type.

[Swift] 纯文本查看 复制代码
extension NSURL : ThrowableTaskType {

    public typealias ReturnType = (NSData, NSURLResponse)

    public func action(completion: Result<ReturnType> -> ()) {
        ThrowableTask<ReturnType> {
            let session = NSURLSession(configuration: .ephemeralSessionConfiguration())
            let (data, response, error) = Task { callback in session.dataTaskWithURL(self, completionHandler: callback).resume()}.await()
            guard error == nil else { throw error! }
            return (data!, response!)
        }.asyncResult(completion: completion)
    }

}


This extension allows us to write the following code:

[Swift] 纯文本查看 复制代码
let (data, response) = try! NSURL(string: "www.google.com")!.await()


A Task can represent more complicated activities, even those involving UI. In the following example, we use an ImagePickerTask to launch a UIImagePickerViewController and wait for the user to choose an image. Once the user selects an image or press the cancel button, the view controller dismisses, and the task returns with the selected image.

[Swift] 纯文本查看 复制代码
class ImagePickerDemoViewController: UIViewController {

    let imageView = UIImageView()

    func launchImagePicker() {
        Task {
            do {
                let data = try ImagePickerTask(viewController: self).await()
            } catch Error.PhotoLibraryNotAvailable {
                alert("Photo Library is Not Available")
            }
            guard let image = data?[UIImagePickerControllerOriginalImage] as? UIImage else {
                self.imageView.image = nil
                return
            }
            self.imageView.image = image
        }.async()
    }

}


The ImagePickerTask knows when the user has picked an image or canceled because it is the UIImagePickerViewController’s delegate. For more details, see its implementation and the example folder.




Example

To run the example project, clone the repo, and run pod install from the Example directory first.

You may also want to take a look at the test cases.




Author

Zhixuan Lai, zhxnlai@gmail.com




License

AsyncTask is available under the MIT license. See the LICENSE file for more info.




Github

https://github.com/zhxnlai/AsyncTask

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

嗯,不错!期待更多好内容,支持一把:
支持敏捷大拇指,用支付宝支付10.24元 支持敏捷大拇指,用微信支付10.24元

评分

参与人数 1金钱 +10 收起 理由
Anewczs + 10 发一帖,长一智!赞一个!

查看全部评分

本帖被以下淘专辑推荐:

3rdev 发表于 2016-6-23 18:09:31 | 显示全部楼层
有机会用一用~~
代码买卖 发表于 2016-9-12 09:46:03 | 显示全部楼层
mark~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

做任务,领红包。
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表