如何沿承诺链向下传递数据?

ldi*_*ual 3 promise swift promisekit

假设我想生成一个需要多个承诺才能解决的数据集,我如何将每个结果存储在承诺链中,以便我可以一次性创建我的最终数据集?

struct CompleteData {
    let a: String
    let b: String
}

func getData() -> Promise<CompleteData> {
    getA().then { a -> Promise<String> in
        return a.getB()
    }.then { b -> CompleteData in
        return CompleteData(a: ???, b: b)
    }
}
Run Code Online (Sandbox Code Playgroud)

我提出的解决方案不够优雅:

临时 IUO

使用隐式解包的选项来存储临时值。如果我忘记分配给a.

func getData() -> Promise<CompleteData> {
    var a: String!
    getA().then { _a -> Promise<String> in
        _a = a
        return _a.getB()
    }.then { b -> CompleteData in
        return CompleteData(a: a, b: b)
    }
}
Run Code Online (Sandbox Code Playgroud)

嵌套承诺

从外部作用域嵌套承诺和访问值。这通过进入嵌套地狱而违背了 Promise 的目的。

func getData() -> Promise<CompleteData> {
    getA().then { a -> Promise<CompleteData> in
        return a.getB().then { b -> CompleteData in
            return CompleteData(a: a, b: b)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我头顶上的其他解决方案:使用可选字段 in CompleteData,使用var字段 inCompleteData并在链解析时分配,这些都不适合我。

有人能想到一个更优雅的方法来做到这一点吗?

小智 5

您可以使用元组将数据向下传递到承诺链。您只需要指定元组和“a”返回承诺。使用 .map 返回元组。这是您示例中的代码:

struct CompleteData {
    let a: String
    let b: String
}

func getData() -> Promise<CompleteData> {
    getA().then { a -> Promise<(String, a)> in
        return a.getB().map{ ($0, a) }
        }.then { (b, a) -> CompleteData in
            return CompleteData(a: a, b: b)
    }
}
Run Code Online (Sandbox Code Playgroud)

PromiseKit 文档

希望它会帮助你。干杯:)