小编典典

如何在 .then() 链中访问先前的承诺结果?

all

我已经将我的代码重组为Promise,并构建了一个美妙的长而
扁平的 Promise 链 ,由多个.then()回调组成。最后我想返回一些复合值,并且需要访问多个 中间承诺结果
。但是,序列中间的分辨率值不在最后一个回调的范围内,我该如何访问它们?

function getExample() {
    return promiseA(…).then(function(resultA) {
        // Some processing
        return promiseB(…);
    }).then(function(resultB) {
        // More processing
        return // How do I gain access to resultA here?
    });
}

阅读 202

收藏
2022-03-03

共1个答案

小编典典

ECMAScript 和谐

当然,这个问题也得到了语言设计者的认可。他们做了很多工作,异步函数提案最终成为了

ECMAScript 8

您不再需要单个then调用或回调函数,因为在异步函数中(在被调用时返回一个 Promise),您可以简单地等待 Promise
直接解析。它还具有任意控制结构,例如条件、循环和 try-catch 子句,但为了方便起见,我们在这里不需要它们:

async function getExample() {
    var resultA = await promiseA(…);
    // some processing
    var resultB = await promiseB(…);
    // more processing
    return // something using both resultA and resultB
}

ECMAScript 6

在我们等待 ES8 时,我们已经使用了一种非常相似的语法。ES6
带有生成器函数,它允许在任意放置的yield关键字处将执行分成几部分。这些切片可以彼此独立运行,甚至异步运行——这正是我们想要在运行下一步之前等待承诺解决时所做的事情。

有专门的库(如cotask.js),但也有许多
Promise 库具有辅助函数(QBluebirdwhen、“”),当你给它们一个生成器函数时,它们会为你执行这个异步逐步执行产生承诺。

var getExample = Promise.coroutine(function* () {
//               ^^^^^^^^^^^^^^^^^ Bluebird syntax
    var resultA = yield promiseA(…);
    // some processing
    var resultB = yield promiseB(…);
    // more processing
    return // something using both resultA and resultB
});

从 4.0 版开始,这在 Node.js 中确实有效,还有一些浏览器(或其开发版)相对较早地支持生成器语法。

ECMAScript 5

但是,如果您想要/需要向后兼容,则不能使用没有转译器的那些。当前工具支持生成器函数和异步函数,例如参见 Babel
关于生成器异步函数的文档。

然后,还有许多其他 专门用于简化异步编程的 compile-to-JS
语言。
它们通常使用类似于await, 的语法(例如Iced
CoffeeScript
),但也有其他具有类似 Haskell
符号的do语法(例如LatteJsmonadicPureScriptLispyScript)。

2022-03-03