测试已测试 | ✓ |
Lang语言 | SwiftSwift |
许可证 | MIT |
发布上次发布 | 2016年12月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由 Troy Stribling 维护。
Scala Futures 的一个 Swift 实现,包含更多功能。
在非阻塞式异步请求和串行化请求处理、错误恢复和过滤的连接接口上有 Futures
的界面。在大多数 iOS 库中,异步接口是通过代理协议模式实现,或在一些情况下使用回调。即使简单的实现也可能导致业务逻辑分散到多个文件或深度嵌套的回调,使得难以跟踪。将看到 Futures
悠然解决了这个问题。
SimpleFutures 是 Futures
在 Swift 上的一个实现,受 BrightFutures 的启发。
git submodule
。另一个选项是将 SimpleFutures.swift
直接添加到您的项目中,因为整个库都包含在一个文件中。
提供了一个简单的围绕 GCD
的包装。
// create a queue with .background pos
let queue = Queue("us.gnos.myqueue")
// run block synchronously on queue
queue.sync {
// do something
}
// return a value from a synchronous task
let result = queue.sync {
// do something
return value
}
// run block asynchronously on queue
queue.async {
// do something
}
// run block asynchronously at specified number of seconds from now
queue.delay(10.0) {
// do something
}
执行上下文
执行任务,并通过协议的实现来定义它,
public protocol ExecutionContext {
func execute(task: Void -> Void)
}
SimpleFutures
提供一个 QueueContext
,它在指定的 Queue
上异步执行任务,以及一个 ImmediateContext
,它在调用线程上同步执行任务。
// main and global queue contexts
QueueContext.main
QueueContext.global
// create a QueueContext using queue
public init(queue: Queue)
// immediate context runs tasks synchronously on the calling thread
ImmediateContext()
Futures
和 FutureStreams
的完成处理程序和组合器在指定的上下文中运行。默认上下文是 QueueContext.main
。
ImmediateContext()
对于测试可能很有用。
Future
实例是对可以在未来的任何时候计算的不变结果的只读封装。当结果被计算时,称 Future
已完成。一个 Future
可以成功完成并返回一个值,或者因为错误而失败。
Future
还提供组合方法,允许多个实例一起链式调用并顺序执行,同时还提供了可以同时评估多个 Futures
的容器方法。
本节将讨论这些主题的每个细节。
Future
可以使用 future
方法、一个 Promise
或初始化器进行创建。
init
init
方法可用于创建具有指定结果的未来。
// create an uncompleted future
public init()
// create a future with result of type T
public init(value: T)
// create a Future with an error result
public init(error: Swift.Error)
future
提供了几种版本的 future
以便于与现有代码集成。
最简单的版本接受一个同步的 @autoclosure
或闭包。
// task is executed synchronously
public func future<T>( _ task: @autoclosure @escaping (Void) -> T) -> Future<T>
// task is executed in context which may be asynchronous
public func future<T>(context: ExecutionContext = QueueContext.futuresDefault, _ task: @escaping (Void) throws -> T) -> Future<T>
还提供了接受异步闭包参数的版本,这些闭包参数遵循常见的完成块形式。
public func future<T>(method: (@escaping (T, Swift.Error?) -> Void) -> Void) -> Future<T>
public func future<T>(method: (@escaping (T, Swift.Error?) -> Void) -> Void) -> Future<T>
public func future<T>(method: (@escaping (T) -> Void) -> Void) -> Future<T>
使用 future
简单地向现有代码中添加 Future
接口。考虑以下类,它有一个异步请求,接受完成块:
class AsyncRequester {
func request(completion: @escaping (Int?, Swift.Error?) -> Void)
}
为添加 Future
接口添加一个扩展将看起来像:
extension AsyncRequester {
func futureRequest() -> Future<Int?> {
return future(method: request)
}
}
Promise
Promise
实例是 一次性可写的,并包含一个 Future
。当 成功完成 其 Future
时,Promise
将值写入 Future
结果,当 失败完成 时将错误写入其 Future
结果。
// Create and uncompleted Promise
public init()
// Completed Promise with another Future
public func completeWith(context: ExecutionContext = QueueContext.futuresDefault, future: Future<T>)
// Complete Promise successfully with value
public func success(_ value: T)
// Complete Promise with error
public func failure(_ error: Swift.Error)
Future
接口实现可以使用 Promise
来创建和管理 Future
。
下面是一个简单的 URLSession
extension
,它添加了一个执行 HTTP
GET
请求并返回 Future
的方法。
extension URLSession {
class func get(with url: URL) -> Future<(Data?, URLResponse?)> {
let promise = Promise<(Data?, URLResponse?)>()
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
promise.failure(error)
} else {
promise.success((data, response))
}
}
task.resume()
return promise.future
}
}
在应用程序中使用:
let requestFuture = URLSession.get(with: URL(string: "http://troystribling.com")!)
设置 Future
结果的值 完成 它。持有 Future
参考的实体通过方法 onSuccess
和 onFailure
通知 完成。上一节中的 requestFuture
会使用以下方法处理 完成 事件:
requestFuture.onSuccess { (data, response) in
guard let response = response, let data = data else {
return
}
// process data
}
requestFuture.onFailure { error in
// handle error
}
可以为单个 Future
定义多个完成处理程序。
Future
可以使用 completeWith
使用另一个 Future
的结果来完成。
public func completeWith(context: ExecutionContext = QueueContext.futuresDefault, future: Future<T>)
例如:
let anotherFuture = Future<Int>()
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
let dependentFuture = future(method: asyncRequest)
anotherFuture.completeWith(future: dependentFuture)
组合器是用于构建一个序列化的 Future
链(执行异步请求并应用映射和过滤请求结果)的方法。
将 mapping: (T) throws -> M
应用到成功的 Future<T>
结果,以产生一个不同类型的 Future<M>
。
public func map<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> M) -> Future<M>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
let mappedFuture = future(method: asyncRequest).map { value -> String in
guard value < 0 else {
throw AppError.invalidValue
}
return "\(value)"
}
将一个mapping: (T) throws -> Future
应用到成功的Future
返回的Future
上。使用flatMap
来串行异步请求。
public func flatMap<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> Future<M>) -> Future<M>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func asyncMapping(Int) -> Future<String>
let mappedFuture = future(method: asyncRequest).flatMap { value -> Future<String> in
guard value < 0 else {
throw AppError.invalidValue
}
return asyncMapping(value)
}
flatMap
通常需要指定闭包的返回类型。它是一个重载方法,编译器有时需要帮助来确定使用哪个。
将一个filter: (T) throws -> Bool
应用到成功的Future
上,如果filter过滤成功,则返回Future
,如果filter失败,则抛出FuturesError.noSuchElement
。
public func withFilter(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), filter: @escaping (T) throws -> Bool) -> Future<T>
例如:
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
let filteredFuture = future(method: asyncRequest).withFilter { value in
value > 0
}
将一个映射apply: (T) -> Void
应用到成功的Future
上。这等价于使用完成处理器onSuccess
。
public func forEach(context:ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), apply: @escaping (T) -> Void)
例如:
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func apply(Int) -> Void
let forEachFuture = future(method: asyncRequest).forEach { value in
apply(value)
}
将一个映射apply: (T) -> Void
应用到成功的Future
上,并返回一个原生的future完成后的结果Future
。这等价于一个透传。在这里可以在组合链中处理数据,但不会影响Future
的result
。
public func andThen(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), completion: @escaping (T) -> Void) -> Future<T>
例如:
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func apply(Int) -> Void
let andThenFuture = future(method: asyncRequest).andThen { value in
apply(value)
}
将一个恢复映射recovery: (Swift.Error) throws -> T
应用到失败的Future
并返回一个Future
。
public func recover(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), recovery: @escaping (Swift.Error) throws -> T) -> Future<T>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func recovery(Swift.Error) -> Int
let recoveryFuture = future(method: asyncRequest).recover { error in
guard let appError = error as? AppError else {
throw error
}
return recovery(appError)
}
将一个恢复映射recovery: (Swift.Error) throws -> Future
应用到失败的Future
并返回一个Future
。
public func recoverWith(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), recovery: @escaping (Swift.Error) throws -> Future<T>) -> Future<T>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func recovery(Swift.Error) -> Future<Int>
let recoveryFuture = future(method: asyncRequest).recoverWith { error -> Future<Int> in
guard let appError = error as? AppError else {
throw error
}
return recovery(appError)
}
recoverWith
通常需要指定闭包的返回类型。它是一个重载方法,编译器有时需要帮助来确定使用哪个。
将一个映射mapping: (Swift.Error) -> Swift.Error
应用到失败的Future
并返回一个带有新错误结果的Future
。
public func mapError(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (Swift.Error) -> Swift.Error) -> Future<T>
例如,将任何Swift.Error
转换为AppError
,
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func mapping(Swift.Error) -> AppError.Error
let mapErrorFuture = future(method: asyncRequest).mapError { error in
guard let appError = error as? AppError else {
return mapping(error)
}
return appError
}
将一个mapping: (R, Iterator.Element.T) throws -> R
应用到数组[Future
上,将结果累积到新的Future
中。如果任何一个Future
失败,则Future
也会失败。
public func fold<R>(context: ExecutionContext = QueueContext.futuresDefault, initial: R, combine: @escaping (R, Iterator.Element.T) throws -> R) -> Future<R>
例如:
fun asyncTask(Int) -> Future<Int>
let futures = [asyncTask(1), asyncTask(1), asyncTask(1)]
let foldFuture = futures.fold(initial: 0) { $0 + $1 }
将[Future
转换为在[Future
完成时完成数组所有结果的Future<[T]>
。使用sequence
来累积无关异步请求的结果。
public func sequence(context: ExecutionContext = QueueContext.futuresDefault) -> Future<[Iterator.Element.T]>
例如:
fun asyncTask(Int) -> Future<Int>
let futures = [asyncTask(1), asyncTask(1), asyncTask(1)]
let sequenceFuture = futures.sequence()
一个Future
可以在应用程序中传递来通知不同组件的事件。可以指定多个完成处理器定义和组合链。并非所有的应用程序组件都会对这个事件感兴趣,可能想”退订“。
应用程序可以使用CancelToken()
取消多个完成处理器回调和组合执行。
fun asyncRequest() -> Int
fun anotherAsyncRequest() -> Future<String>
let cancelToken = CancelToken()
let cancelFuture = future(method: asyncRequest)
let mappedFuture = cancelFuture.flatMap(cancelToken: cancelToken) {
anotherAsyncRequest()
}
mappedFuture.onSuccess(cancelToken: cancelToken) { value in
// process data
}
mappedFuture.onFailure(cancelToken: cancelToken) { ==error in
// process data
}
cancelFuture.cancel(cancelToken)
在诸如CoreLocation
之类的框架中,CLLocationManager
的单个实例可能会反复调用CLLocationManagerDelegate
方法。
func locationManager(_ manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!)
由于Futures
是不可变的,每次调用都必须创建一个新的实例。FutureStreams
是只读的完成Future
容器,可以用于在这种情况下以指定的容量持久保存所有过去的调用。FutureStreams
支持类似于Futures
的接口,可以使用组合子与它们一起使用。
可以使用futureStream
方法、StreamPromise
或初始化器创建FutureStream
。
init
init
方法可用于创建具有指定结果的未来。
// create an empty FutureStream with capacity
public init(capacity: Int)
// create a FutureStream with an Int result and capacity of 10
public init(value: T, capacity: Int)
// create a FutureStream with an error result and capacity of 10
public init(error: Swift.Error, capacity: Int)
futureStream
提供了几个版本的futureStream
,以简化与现有代码的集成。
最简单的一种接受一个同步闭包并在指定的上下文中执行它。
public func futureStream<T>(context: ExecutionContext = QueueContext.futuresDefault, _ task: @escaping (Void) throws -> T) -> FutureStream<T>
还提供了接受常见完成块闭包参数的版本。
public func futureStream<T>(method: (@escaping (T, Swift.Error?) -> Void) -> Void) -> FutureStream<T>
public func futureStream(method: (@escaping (Swift.Error?) -> Void) -> Void) -> FutureStream<Void>
public func futureStream<T>(method: (@escaping (T) -> Void) -> Void) -> FutureStream<T>
使用futureStream
,向现有代码添加FutureStream
接口很简单。考虑以下一个带有完成块异步请求的类,
class TestStreamRequester {
func request(completion: @escaping (Int?, Swift.Error?) -> Void)}
}
extension TestStreamRequester {
func streamRequest() -> FutureStream<Int?> {
return futureStream(method: request)
}
}
StreamPromise
类似于Promise
,StreamPromise
是只写的。它创建并完成 Futures
并将它们添加到FutureStream
中。
// Create and uncompleted StreamPromise with capacity
public init(capacity: Int = Int.max)
// Complete StreamPromise with another Future
public func completeWith(context: ExecutionContext = QueueContext.futuresDefault, future: Future<T>)
// Complete StreamPromise with another FutureStream
public func completeWith(context: ExecutionContext = QueueContext.futuresDefault, stream: FutureStream<T>)
// Complete StreamPromise successfully with value
public func success(_ value: T)
// Complete StreamPromise with error
public func failure(_ error: Swift.Error)
FutureStream
接口实现可以使用StreamPromise
创建FutureStream
。
在此,一个简单的Accelerometer
服务实现被展示,通过FutureStream
提供加速度计数据更新。
import UIKit
import CoreMotion
import BlueCapKit
class Accelerometer {
var motionManager = CMMotionManager()
let queue = OperationQueue.main
let accelerationDataPromise = StreamPromise<CMAcceleration>(capacity: 10)
var updatePeriod: TimeInterval {
get {
return motionManager.accelerometerUpdateInterval
}
set {
motionManager.accelerometerUpdateInterval = newValue
}
}
var accelerometerActive: Bool {
return motionManager.isAccelerometerActive
}
var accelerometerAvailable: Bool {
return motionManager.isAccelerometerAvailable
}
init() {
motionManager.accelerometerUpdateInterval = 1.0
}
func startAcceleromterUpdates() -> FutureStream<CMAcceleration> {
motionManager.startAccelerometerUpdates(to: queue) { [unowned self] (data: CMAccelerometerData?, error: Error?) in
if let error = error {
self.accelerationDataPromise.failure(error)
} else {
if let data = data {
self.accelerationDataPromise.success(data.acceleration)
}
}
}
return accelerationDataPromise.stream
}
func stopAccelerometerUpdates() {
motionManager.stopAccelerometerUpdates()
}
}
在应用程序中使用:
let accelerometer = Accelerometer()
let accelrometerDataFuture = accelerometer.startAcceleromterUpdates()
向FutureStream
添加一个完成 Future
将调用其完成处理程序。当通过onSuccess
和onFailure
方法向FutureStream
添加一个完成 Future
时,保持FutureStream
引用的对象将被通知。前一节中的accelerometerDataFuture
将通过以下方式处理完成事件:
accelrometerDataFuture.onSuccess { data in
// process data
}
accelrometerDataFuture.onFailure { error in
// handle error
}
可以为单个FutureStream
定义多个完成处理程序。
可以使用completeWith
使用另一个Future
或FutureStream
的结果完成一个FutureStream
。
func completeWith(context: ExecutionContext = QueueContext.futuresDefault, stream: FutureStream<T>)
func completeWith(context: ExecutionContext = QueueContext.futuresDefault, future: Future<T>)
例如:
let anotherFutureStream = FutureStream<Int>()
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
// Complete FutureStream with dependent Future
let dependentFuture = future(method: asyncRequest)
anotherFutureStream.completeWith(future: dependentFuture)
// Complete FutureStream with dependent FutureStream
let dependentStream = futureStream(method: asyncRequest)
anotherFutureStream.completeWith(future: dependentStream)
组合子是用于构造一个序列化链的FutureStreams
的方法,该链执行异步请求并应用映射和过滤。
将mapping: (T) throws -> M
应用到成功的FutureStream<T>
的结果,以产生一个不同类型的FutureStream<M>
。
public func map<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> M) -> FutureStream<M>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
let mappedStream = futureStream(method: asyncRequest).map { value -> String in
guard value < 0 else {
throw AppError.invalidValue
}
return "\(value)"
}
mapping
将在相关的依赖于的FutureStream
成功完成时被调用。
对成功的FutureStream<T>
的结果应用futureMapping: (T) throws -> Future<M>
或streamMapping: (T) throws -> FutureStream<M>
返回FutureStream<M>
。使用flatMap
对异步请求和流进行序列化。
// Apply a mapping returning a FutureStream to a FutureStream result
public func flatMap<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> FutureStream<M>) -> FutureStream<M>
// Apply a mapping returning a Future to a FutureStream result
public func flatMap<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> Future<M>) -> FutureStream<M>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func streamMapping(Int) -> FutureStream<String>
let mappedStream = futureStream(method: asyncRequest).flatMap { value -> FutureStream<String> in
guard value < 0 else {
throw AppError.invalidValue
}
return streamMapping(value)
}
和
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func futureMapping(Int) -> Future<String>
let mappedStream = futureStream(method: asyncRequest).flatMap { value -> Future<String> in
guard value < 0 else {
throw AppError.invalidValue
}
return futureMapping(value)
}
可以将映射 streamMapping: (T) throws -> FutureStream<M>
应用到成功的 Future<T>
的结果中,从而返回一个 FutureStream<M>
。
// Apply a mapping to Future returning a FutureStream
public func flatMap<M>(capacity: Int = Int.max, context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> FutureStream<M>) -> FutureStream<M>
例如:
let mappedStream = futureStream(method: asyncRequest).flatMap { value -> FutureStream<String> in
guard value < 0 else {
throw AppError.invalidValue
}
return streamMapping(value)
}
flatMap
通常需要指定闭包的返回类型。它是一个重载方法,编译器有时需要帮助来确定使用哪个。
将 filter: (T) throws -> Bool
应用到成功的 FutureStream<T>
的结果中。如果过滤器成功,则返回 FutureStream<T>
,如果过滤器失败,则抛出 FuturesError.noSuchElement
。
public func withFilter(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), filter: @escaping (T) throws -> Bool) -> FutureStream<T>
例如:
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
let filteredStream = futureStream(method: asyncRequest).withFilter { value in
value > 0
}
将映射 apply: (T) -> Void
应用到一个成功的 FutureStream<T>
。这相当于使用 onSuccess
完成处理程序。
public func forEach(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), apply: @escaping (T) -> Void)
例如:
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func apply(Int) -> Void
let forEachStream = futureStream(method: asyncRequest).forEach { value in
apply(value)
}
将映射 apply: (T) -> Void
应用到成功的 FutureStream<T>
并返回一个用原始流的结果完成的 FutureStream<T>
。这相当于转发。在这里可以处理数据组合链,但不会影响 FutureStream<T>
的结果。
public func andThen(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), completion: @escaping (T) -> Void) -> FutureStream<T>
例如:
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func apply(Int) -> Void
let andThenStream = futureStream(method: asyncRequest).andThen { value in
apply(value)
}
将对 FutureStream<T>
失败应用恢复映射 recovery: (Swift.Error) throws -> T
返回 FutureStream<T>
。
public func recover(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), recovery: @escaping (Swift.Error) throws -> T) -> FutureStream<T>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func recovery(Swift.Error) -> Int
let recoveryStream = futureStream(method: asyncRequest).recover { error in
guard let appError = error as? AppError else {
throw error
}
return recovery(appError)
}
将对 FutureStream<T>
失败应用恢复映射 futureRecovery: (Swift.Error) throws -> Future<T>
或 streamRecovery: (Swift.Error) throws -> FutureStream<T>
返回一个 FutureStream。
// Apply a recovery returning a FutureStream to a FutureStream result
public func recoverWith(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), recovery: @escaping (Swift.Error) throws -> FutureStream<T>) -> FutureStream<T>
// Apply a recovery returning a Future to a FutureStream result
public func flatMap<M>(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (T) throws -> Future<M>) -> FutureStream<M>
例如:
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func streamRecovery(Swift.Error) -> FutureStream<Int>
let recoveryStream = futureStream(method: asyncRequest).recoverWith { error -> FutureStream<Int> in
guard let appError = error as? AppError else {
throw error
}
return streamRecovery(appError)
}
和
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func futureRecovery(Swift.Error) -> Future<Int>
let recoveryStream = futureStream(method: asyncRequest).recoverWith { value -> Future<String> in
guard value < 0 else {
throw AppError.invalidValue
}
return futureRecovery(value)
}
将 streamRecovery: (Swift.Error) throws -> FutureStream<T>
也可以应用于失败的 Future<T>
,返回一个 FutureStream<M>
。
public func recoverWith(capacity: Int = Int.max, context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), recovery: @escaping (Swift.Error) throws -> FutureStream<T>) -> FutureStream<T>
例如:
let recoveryStream = futureStream(method: asyncRequest).recoverWith { error -> FutureStream<Int> in
guard let appError = error as? AppError else {
throw error
}
return streamRecovery(appError)
}
recoverWith
通常需要指定闭包的返回类型。它是一个重载方法,编译器有时需要帮助来确定使用哪个。
将对 FutureStream<T>
失败应用映射 mapping: (Swift.Error) -> Swift.Error
并返回一个具有映射错误结果的 FutureStream<T>
。
public func mapError(context: ExecutionContext = QueueContext.futuresDefault, cancelToken: CancelToken = CancelToken(), mapping: @escaping (Swift.Error) -> Swift.Error) -> FutureStream<T>
例如,将任何Swift.Error
转换为AppError
,
enum AppError: Error {
case invalidValue
}
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
func mapping(Swift.Error) -> AppError
let mapErrorStream = futureStream(method: asyncRequest).mapError { error in
guard let appError = error as? AppError else {
return mapping(error)
}
return appError
}
可以将 FutureStream
在应用程序中传递,以通知不同的组件事件。可以指定多个完成处理程序定义和组合链。并非所有应用程序组件都对事件感兴趣,并且可能想要'退订'。
应用程序可以使用CancelToken()
取消多个完成处理器回调和组合执行。
func asyncRequest(_ completion: @escaping (Int, Swift.Error?) -> Void)
fun asyncStream() -> FutureStream<String>
let cancelToken = CancelToken()
let cancelStream = futureStream(method: asyncRequest)
let mappedStream = cancelStream.flatMap(cancelToken: cancelToken) {
asyncStream()
}
mappedStream.onSuccess(cancelToken: cancelToken) { value in
// process data
}
mappedStream.onFailure(cancelToken: cancelToken) { ==error in
// process data
}
cancelFuture.cancel(cancelToken)
测试用例可提供。要构建 workspace
,
pod install
并在生成的 workspace
的 test
选项卡中运行。
以下项目使用 SimpleFutures。它们可以用作实际应用使用的指南。
Futures
的 CoreBluetooth 替换。Futures
的 CoreLocation 替换。