在多个其他承诺完成后,您可以使用when或join开始某些事情。不同之处在于他们如何处理失败的承诺。听起来你想加入。这是一个具体但简单的示例。
第一个代码块是一个示例,说明如何创建 2 个 Promise 链,然后等待它们都完成,然后再开始下一个任务。正在完成的实际工作被抽象为一些功能。关注这段代码,因为它包含您需要的所有概念信息。
片段
let chain1 = firstly(execute: { () -> (Promise<String>, Promise<String>) in
let secondPieceOfInformation = "otherInfo" // This static data is for demonstration only
// Pass 2 promises, now the next `then` block will be called when both are fulfilled
// Promise initialized with values are already fulfilled, so the effect is identical
// to just returning the single promise, you can do a tuple of up to 5 promises/values
return (fetchUserData(), Promise(value: secondPieceOfInformation))
}).then { (result: String, secondResult: String) -> Promise<String> in
self.fetchUpdatedUserImage()
}
let chain2 = firstly {
fetchNewsFeed() //This promise returns an array
}.then { (result: [String : Any]) -> Promise<String> in
for (key, value) in result {
print("\(key) \(value)")
}
// now `result` is a collection
return self.fetchFeedItemHeroImages()
}
join(chain1, chain2).always {
// You can use `always` if you don't care about the earlier values
let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(self.methodStart)
print(String(format: "All promises finished %.2f seconds later", executionTime))
}
PromiseKit 使用闭包来提供它的 API。闭包有一个范围,就像一个if
语句。如果您在语句的范围内定义一个值if
,那么您将无法在该范围之外访问它。
您有几个选项可以将多条数据传递到下一个then
块。
- 使用与所有 Promise 共享范围的变量(您可能希望避免这种情况,因为它在管理异步数据传播流时对您不利)
- 使用自定义数据类型来保存两个(或更多)值。这可以是元组、结构、类或枚举。
- 使用集合(例如字典),例如
chain2
- 返回一个承诺元组,示例包含在
chain1
在选择方法时,您需要做出最佳判断。
完整代码
import UIKit
import PromiseKit
class ViewController: UIViewController {
let methodStart = Date()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
<<Insert The Other Code Snippet Here To Complete The Code>>
// I'll also mention that `join` is being deprecated in PromiseKit
// It provides `when(resolved:)`, which acts just like `join` and
// `when(fulfilled:)` which fails as soon as any of the promises fail
when(resolved: chain1, chain2).then { (results) -> Promise<String> in
for case .fulfilled(let value) in results {
// These promises succeeded, and the values will be what is return from
// the last promises in chain1 and chain2
print("Promise value is: \(value)")
}
for case .rejected(let error) in results {
// These promises failed
print("Promise value is: \(error)")
}
return Promise(value: "finished")
}.catch { error in
// With the caveat that `when` never rejects
}
}
func fetchUserData() -> Promise<String> {
let promise = Promise<String> { (fulfill, reject) in
// These dispatch queue delays are standins for your long-running asynchronous tasks
// They might be network calls, or batch file processing, etc
// So, they're just here to provide a concise, illustrative, working example
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(self.methodStart)
print(String(format: "promise1 %.2f seconds later", executionTime))
fulfill("promise1")
}
}
return promise
}
func fetchUpdatedUserImage() -> Promise<String> {
let promise = Promise<String> { (fulfill, reject) in
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(self.methodStart)
print(String(format: "promise2 %.2f seconds later", executionTime))
fulfill("promise2")
}
}
return promise
}
func fetchNewsFeed() -> Promise<[String : Any]> {
let promise = Promise<[String : Any]> { (fulfill, reject) in
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(self.methodStart)
print(String(format: "promise3 %.2f seconds later", executionTime))
fulfill(["key1" : Date(),
"array" : ["my", "array"]])
}
}
return promise
}
func fetchFeedItemHeroImages() -> Promise<String> {
let promise = Promise<String> { (fulfill, reject) in
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(self.methodStart)
print(String(format: "promise4 %.2f seconds later", executionTime))
fulfill("promise4")
}
}
return promise
}
}
输出
promise3 1.05 秒后
array ["my", "array"]
key1 2017-07-18 13:52:06 +0000
promise1 2.04 秒后
promise4 3.22 秒后
promise2 4.04 秒后
所有 promises 完成 4.04 秒后
Promise 值为:promise2
承诺值是:promise4