描述
When 是 Swift 中对 Promises 的轻量级实现。它不包括任何针对 iOS 和 OSX 的辅助函数,这是故意的,为了减少冗余复杂度,并给您更多的自由和灵活性作出选择。由于 Swift 的泛型,它是类型安全的,因此您可以创建任何类型所需的 promises。
When 可以轻松集成到您的项目和库中,将您的异步代码提升到下一个水平。
目录
为什么?
为了使异步代码更加易读和标准化
fetchJSON().then({ data: NSData -> [[String: AnyObject]] in
// Convert to JSON
return json
}).then({ json: [[String: AnyObject]] -> [Entity] in
// Map JSON
// Save to database
return items
}).done({ items: [Entity] in
self.items = items
self.tableView.reloadData()
}).error({ error in
print(error)
})
使用方法
Promise
promise(承诺)表示任务将来的值。承诺从挂起状态开始,然后可以通过一个值解决或者通过一个错误拒绝。
// Creates a new promise that could be resolved with a String value
let promise = Promise<String>()
// Resolves the promise
promise.resolve("String")
// Or rejects the promise
promise.reject(Error.notFound)
// Creates a new promise that is resolved with a String value
let promise = Promise({
return "String"
})
// Creates a new promise that is rejected with an Error
let promise = Promise({
//...
throw Error.notFound
})
当前 promise 的回调和所有通过 then 创建的链式承诺的回调默认在主队列上执行,但您可以在 init
中指定所需队列。
let promise = Promise<String>(queue: dispatch_get_main_queue())
完成
添加处理程序以处理当 promise 对象通过一个值被解决时。
// Create a new promise in a pending state
let promise = Promise<String>()
// Add done callback
promise.done({ value in
print(value)
})
// Resolve the promise
promise.resolve("String")
失败
添加处理程序以处理当 promise 对象通过一个 Error
被拒绝时。
// Create a new promise in a pending state
let promise = Promise<String>()
// Add fail callback
promise.fail({ error in
print(error)
})
// Reject the promise
promise.reject(Error.notFound)
也可以取消承诺,这意味着它将通过错误 PromiseError.cancelled
拒绝。如果你想在 fail
处理程序中忽略此错误,可以使用 FailurePolicy
。
// Create a new promise in a pending state
let promise = Promise<String>()
// This callback will not be called when a promise is cancelled
promise.fail({ error in
print(error)
})
// This callback will be called when a promise is cancelled
promise.fail(policy: .allErrors, { error in
print(error)
})
// Cancel the promise
promise.cancel()
总是
添加处理程序以处理当 promise 对象要么解决要么拒绝时。此回调将在 完成 或 失败 处理程序之后调用。
// Create a new promise in a pending state
let promise = Promise<String>()
// Add always callback
promise.always({ result in
switch result {
case let .success(value):
print(value)
case let .failure(error):
print(error)
}
})
// Resolve or reject the promise
promise.resolve("String") // promise.reject(Error.notFound)
然后
返回一个新的promise,可以使用当前promise的结果值。这意味着您可以轻松创建promise链来简化复杂的异步操作,使其逻辑清晰易懂。
当使用提供的闭包时,以返回值解决新的promise。
let promise = Promise<NSData>()
promise
.then({ data -> Int in
return data.length
}).then({ length -> Bool in
return length > 5
}).done({ value in
print(value)
})
promise.resolve("String".dataUsingEncoding(NSUTF8StringEncoding)!)
当从提供的闭包返回的promise解决时,新的promise解决。
struct Networking {
static func GET(url: NSURL) -> Promise<NSData> {
let promise = Promise<NSData>()
//...
return promise
}
}
Networking.GET(url1)
.then({ data -> Promise<NSData> in
//...
return Networking.GET(url2)
}).then({ data -> Int in
return data.length
}).done({ value in
print(value)
})
then闭包默认在主队列上执行,但您可以将所需的队列作为参数传递。
promise.then(on: dispatch_get_global_queue(QOS_CLASS_UTILITY, 0))({ data -> Int in
//...
})
如果您想使用后台队列,有一些辅助方法可以这样做。
promise1.thenInBackground({ data -> Int in
//...
})
promise2.thenInBackground({ data -> Promise<NSData> in
//...
})
恢复
返回一个新的promise,当抛出错误时可以继续链。
let promise = Promise<String>()
// Recover the chain
promise
.recover({ error -> Promise<String> in
return Promise({
return "Recovered"
})
})
.done({ string in
print(string) // Recovered
})
// Reject the promise
promise.reject(Error.notFound)
当
提供了一种方式根据一个或多个promises来执行回调函数。该方法返回一个新的"主" promise,该promise跟踪所有传入的promises的聚合状态。当所有promises解决时,方法将解决其"主" promise,或者当其中一个promise被拒绝时,拒绝"主" promise。如果"主" promise解决,则使用每个解析的promise的解决值执行done回调。
let promise1 = Promise<Int>()
let promise2 = Promise<String>()
let promise3 = Promise<Int>()
when(promise1, promise2, promise3)
.done({ value1, value2, value3 in
print(value1)
print(value2)
print(value3)
})
promise1.resolve(1)
promise2.resolve("String")
promise3.resolve(3)
响应式扩展
使用以下扩展来将当与RxSwift集成。
import RxSwift
extension Promise: ObservableConvertibleType {
public func asObservable() -> Observable<T> {
return Observable.create({ observer in
self
.done({ value in
observer.onNext(value)
})
.fail({ error in
observer.onError(error)
})
.always({ _ in
observer.onCompleted()
})
return Disposables.create()
})
}
}
安装
当 通过 CocoaPods 不可用时。要安装它,只需将以下行添加到您的 Podfile 中
pod 'When'
对于 RxSwift
扩展,您可以使用 CocoaPods subspecs
pod 'When/RxSwift'
当 也通过 Carthage 不可用时。要安装,只需编写Cartfile
github "vadymmarkov/When"
作者
瓦迪姆·马尔科夫,[email protected]
鸣谢
灵感来源于 PromiseKit 和 Then。
贡献
有关更多信息,请参阅 CONTRIBUTING 文件。
许可证
When 受 MIT 许可证管理。有关更多信息,请参阅 LICENSE 文件。