AlecrimAsyncKit 4.0

AlecrimAsyncKit 4.0

测试已测试
语言语言 SwiftSwift
许可协议 MIT
发布上次发布2018年5月
SwiftSwift 版本4.0
SPM支持 SPM

Vanderlei Martinelli 维护。



AlecrimAsyncKit

Language: Swift Platforms License: MIT CocoaPods Apps Author: vmartinelli

Swift 的 async 和 await。

使用方法

等待结果

也许我本末倒置了,但... 对于下一节中的所有函数,您都可以以相同的方式等待返回值

func someFuncRunningInBackground() throws {
    let value = try await { self.someLongRunningAsynchronousFunc() }

    // do something with the returned value...
}

您还可以仅在需要时使用结果

func someFuncRunningInBackground() throws {
    // the task starts immediately
    let task = self.someLongRunningAsynchronousFunc()

    // do other things, the task is running...

    // continue doing other things...
    // the task can be still running or maybe it is already finished, who knows?

    //
    let value = try await(task)

    // do something with the returned value...
}

创建异步任务

您可以在 async 闭包中简单返回所需的值。

func someLongRunningAsynchronousFunc -> Task<SomeValuableValue> {
    return async {
        let value = self.createSomeValuableValue()

        // some long running code here...

        return value
    }    
}

但是,如果您正在调用具有完成处理程序的方法,您可能需要一个不同的闭包签名,将其任务本身作为参数,并在工作完成时调用其 finish(with:) 方法。

func someLongRunningAsynchronousFunc -> Task<SomeValuableValue> {
    return async { task in
        self.getSomeValuableValue(completionHandler: { value in
            task.finish(with: value)
        })        
    }    
}

如果完成处理程序有一个错误作为附加参数,您也可以将其传递给 finish 方法(它将在等待任务结果时在 try 语句中处理)。

func someLongRunningAsynchronousFunc -> Task<SomeValuableValue> {
    return async { task in
        self.getSomeValuableValue(completionHandler: { value, error in
            task.finish(with: value, or: error)
        })        
    }    
}

使用 DispatchQueue 和 OperationQueue 创建任务

您还可以使用添加到 DispatchQueueOperationQueue 的便利方法来创建任务

func calculate() -> Double {
    // using DispatchQueue
    let someCalculatedValue = await(DispatchQueue.global(qos: .background).async {
        var value: Double = 0

        // do some long running calculation here

        return value
    } as NonFailableTask<Double>)

    // using OperationQueue
    let operationQueue = OperationQueue()
    operationQueue.qualityOfService = .background

    let operationTask = operationQueue.addOperation {
        var value: Double = 0

        // do some long running calculation here

        return value
    } as NonFailableTask<Double>


    // using the results
    return someCalculatedValue * await(operationTask)
}

取消任务

您可以使用任务的 cancel() 方法在队列中之后取消一个任务。实际上何时取消取决于其内容实现。

AlecrimAsyncKit 中取消任务与用一个带有 NSCocoaErrorDomainNSUserCancelledError 参数的 NSError 完成任务非常相似。但如果您使用 cancel(),可以使用提供的代码块触发取消操作。

您可以添加要在任务以此方式取消时执行的取消代码块

func someLongRunningAsynchronousFunc -> Task<SomeValuableValue> {
    return async { task in
        let token = self.getSomeValuableValue(completionHandler: { value, error in
            task.finish(with: value, or: error)
        })

        // add a closure to be executed when and if the task is cancelled
        task.cancellation += {
           token.invalidate()
        }        
    }    
}

当然,这只能在您使用“扩展”的异步闭包签名时完成,因为您可能需要 task 参数。

当可能时,框架将尝试为子任务“继承”取消操作。这意味着如果父任务被取消,在其实现中开始的任务也可能被取消,而无需进行重大干预。

主线程

由于 await 函数阻塞当前线程,因此您只能在后台 DispatchQueueOperationQueueThread 上等待异步函数。但在主线程上您可以做以下操作

func someFuncRunningInTheMainThread() {
    //
    self.activityIndicator.startAnimating()

    // start the background task
    self.someLongRunningAsynchronousFunc()
        .then { value in
            // when the background work is done,
            // do something with the returned value in the main thread
        }
        .catch { error in
            // do a nice error handling
        }
        .finally {
            self.activityIndicator.stopAnimating()
    }
}

所有方法 (thencatchcancelledfinally)都是可选的。当指定时,无论任务是否被取消或是否发生错误,相关的闭包都会始终调用。

非失败任务

如果您阅读了框架的代码,您会找到 NonFailableTask<Value> 类。这种类型的任务不会失败(有点)。实际上它可能失败,但不应失败。

与可失败的任务相比,主要区别在于在等待非失败任务的结果时不需要 try。非失败任务也不能取消。

只有在您确定该任务不会失败时才请使用此类型。如果它失败了,那么程序将崩溃。

依赖、条件和观察者

上一个版本基于WWDC 2015的第226场会议(“高级NSOperations”)的观察者和条件。这使得框架变得不必要地复杂。如果您现在就需要此功能,可以使用 AlecrimAsyncKit 版本3.x。

在4.0版本中,框架引入了“依赖”的概念,并实现了新的“条件”类型。观察者可能会在未来的版本中重新出现。但没有保证。

贡献

如果您有任何问题或需要更多信息,请使用提供的GitHub链接打开问题。

您也可以通过修复错误或创建新功能来贡献。在这种情况下,请将您的请求提交到该存储库,因为我没有太多时间去“寻找”尚未提交的补丁。

  • master - 生产分支。克隆或分叉此存储库以获取最新版本。
  • develop - 活动开发分支。《拉取请求》[点击此处] 应该指向此分支。

联系作者

许可协议

AlecrimAsyncKit 在MIT许可协议下发布。有关更多信息,请参阅LICENSE。