一个简化的Future<Value, Error>
实现。
Future
Future代表计算结果,可以是现在、将来或永不可用。从本质上讲,Future是一个对象,您可以将其回调附加到该对象,而不是将回调传递给执行计算的函数。
Future易于组合。`Future<Value, Error>`提供一套函数,如`map`、`flatMap`、`zip`、`reduce`等,用于组合Future。
快速入门
使用on(success:failure:completion:)
方法将回调附加到Future
。
let user: Future<User, Error>
user.on(success: { print("received entity: \($0)" },
failure: { print("failed with error: \($0)" })
// As an alternative observe a completion:
user.on(completion: { print("completed with result: \($0)" })
默认情况下,所有回调都在主队列(DispatchQueue.main
)上执行。要更改队列,请将其传递给on
方法。
future.on(queue: .global(), success: { print("value: \($0)" })
映射值
使用熟悉的map
和flatMap
函数转换Future的值和链式Future。
let user: Future<User, Error>
func loadAvatar(url: URL) -> Future<UIImage, Error> {}
let avatar = user
.map { $0.avatarURL }
.flatMap(loadAvatar)
映射错误
Future
拥有类型化错误。要将一个错误类型转换为另一个错误类型,请使用mapError
。
let request: Future<Data, URLError>
request.mapError(MyError.init(urlError:))
使用 flatMapError
来“恢复”错误。
Zip
使用 zip
将最多三个未来的结果合并成一个未来的结果。
let user: Future<User, Error>
let avatar: Future<UIImage, Error>
Future.zip(user, avatar).on(success: { user, avatar in
// use both values
})
或者等待多个未来的结果。
Future.zip([future1, future2]).on(success: { values in
// use an array of values
})
Reduce
使用 reduce
来组合多个未来的结果。
let future1 = Future<Int, Error>(value: 1)
let future2 = Future<Int, Error>(value: 2)
Future.reduce(0, [future1, future2], +).on(success: { value in
print(value) // prints "3"
})
创建未来
使用 Promise
func someAsyncOperation(args) -> Future<Value, Error> {
let promise = Promise<Value, Error>()
someAsyncOperationWithCallback(args) { value, error in
// when finished...
promise.succeed(result: value)
// if error...
promise.fail(error: error)
}
return promise.future
}
使用便捷的初始化方法
let future = Future<Int, Error> { succeed, fail in
someAsyncOperationWithCallback { value, error in
// succeed or fail
}
}
使用值或错误
Future<Int, Error>(value: 1)
Future<Int, Error>(error: Error.unknown)
等待
使用 wait
方法阻塞当前线程,直到未来收到结果为止。
let result = future.wait()
同步检查
class Future<Value, Error> {
var isPending: Bool { get }
var value: Value? { get }
var error: Error? { get }
var result: Result<Value, Error> { get }
}
取消
Pill 将取消视为与 Future
正交的考虑。有几种取消方法。有关于在取消时通过错误终止未来的论点,也有关于在相关工作被取消时永远不解析未来的论点。为了实现取消,您可能需要考虑使用 CancellationToken
或其他类似模式。
反模式
避免嵌套未来,因为这正是未来旨在解决的问题
loadUser().on(success: { user in
loadAvatar(url: user.avatarUrl).on(success: { avatar in
print("avatar loaded")
}
}
需求
- iOS 9.0 / watchOS 2.0 / OS X 10.11 / tvOS 9.0
- Xcode 10
- Swift 4.2
许可
Pill遵循MIT许可协议。更多信息请参阅LICENSE文件。