Futures 是一个用于简化异步编程的跨平台框架,使用 Swift 编写。它轻量级、快速且易于理解。
从根本上讲,Futures 是一个非常简单的框架,由两种类型组成:
Promise
,一个单次赋值容器,生成一个 Future
Future
,一个只读容器,解析为值或错误在许多 Promise 框架中,Promise 与 Future 没有区别。 这引入了 Promise 的可变性,Promise 被传递。 在 Futures 中,Future
是可观察的值,而 Promise
是设置值的函数。
默认情况下,Futures 在单个并发分发队列上被观察。 可以通过将不同的队列分配给 DispatchQueue.futures
来修改此队列。 您还可以为添加到 Future 的每个回调指定您选择的队列。
一个 Future 被认为是:
resolved
(已解决),如果其值已设置fulfilled
(已完成),如果值已设置且成功rejected
(已拒绝),如果值已设置且失败(错误)当函数返回一个 Future<Value>
时,您可以选择直接观察它,或者继续执行更多的异步任务。 对于观察,您可以使用:
whenResolved
,如果您对值和拒绝错误都感兴趣whenFulfilled
,如果您只关心值whenRejected
,如果您只关心错误如果根据第一个 Future 的结果,您有更多异步工作要做,您可以使用:
flatMap()
,基于当前 Future 的结果执行另一个 FutureflatMapIfRejected()
,从当前 Future 可能产生的错误中恢复flatMapThrowing()
,转换当前 Future 的已完成值或返回一个被拒绝的 Futuremap()
,转换当前 Future 的已完成值recover()
,将一个被拒绝的 Future 转换为一个已完成的 Futurealways()
,无论当前 Future 是否被拒绝或已解决,都执行一个返回 Void
的闭包and()
,将两个 Future 的结果组合成一个元组Future<T>.reduce()
,将多个 Future 的结果组合成一个 Future请注意,您可以为所有这些函数指定一个观察分发队列。 例如,您可以使用 flatMap(on: .main)
或 .map(on: .global())
。 默认情况下,队列是 DispatchQueue.futures
。
作为一个简单的例子,以下是一些代码的可能外观:
let future = loadNetworkResource(
from: URL("http://someHost/resource")!
).flatMapThrowing { data in
try jsonDecoder.decode(SomeType.self, from: data)
}.always {
someFunctionToExecuteRegardless()
}
future.whenFulfilled(on: .main) { someType in
// Success
}
future.whenRejected(on: .main) { error in
// Error
}
要创建返回 Future<T>
的函数,您需要创建一个新的待处理 Promise,并在适当的时候解析它。
func performAsynchronousWork() -> Future<String> {
let promise = Promise<String>()
DispatchQueue.global().async {
promise.fulfill(someString)
// If error
promise.reject(error)
}
return promise.future
}
您也可以使用简写。
promise {
try jsonDecoder.decode(SomeType.self, from: data)
} // Future<SomeType>
或者可以从异步返回的简写。
promise(String.self) { completion in
/// ... on success ...
completion(.fulfill("Some string"))
/// ... if error ...
completion(.reject(anError))
} // Future<String>
完整的文档可以在这里找到。
可以使用 Carthage 或 Swift 包管理器将 Futures 添加到您的项目中。
如果您想在您的项目中依赖 Futures,只需在您的 Package.swift
中添加一个 dependencies
子句即可
dependencies: [
.package(url: "https://github.com/davidask/Futures.git", from: "1.6.0")
]
或者,在您的 Cartfile
中添加一个依赖项
github "davidask/Futures"
有关使用 Carthage 的更多详细信息,请访问 这里。
最后,在您的 Swift 文件中导入模块
import Futures
欢迎大家为 Futures 做出贡献,更多信息请查看 LICENSE
文件。
David Ask