如何在 .then() 链中访问先前的承诺结果? [英] How do I access previous promise results in a .then() chain?

查看:30
本文介绍了如何在 .then() 链中访问先前的承诺结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have restructured my code to promises, and built a wonderful long flat promise chain, consisting of multiple .then() callbacks. In the end I want to return some composite value, and need to access multiple intermediate promise results. However the resolution values from the middle of the sequence are not in scope in the last callback, how do I access them?

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?
    });
}

推荐答案

ECMAScript Harmony

当然,这个问题也被语言设计者认识到了.他们做了很多工作,异步函数提案终于成为了

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

You don't need a single then invocation or callback function anymore, as in an asynchronous function (that returns a promise when being called) you can simply wait for promises to resolve directly. It also features arbitrary control structures like conditions, loops and try-catch-clauses, but for the sake of convenience we don't need them here:

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关键字.这些切片可以相互独立,甚至异步运行 - 这就是我们想要在运行下一步之前等待承诺解决方案时所做的.

ECMAScript 6

While we were waiting for ES8, we already did use a very similar kind of syntax. ES6 came with generator functions, which allow breaking the execution apart in pieces at arbitrarily placed yield keywords. Those slices can be run after each other, independently, even asynchronously - and that's just what we do when we want to wait for a promise resolution before running the next step.

有专门的库(例如 cotask.js),但也有许多 Promise 库有辅助函数(Q蓝鸟when, ...) 做 当你给他们一个产生承诺的生成器函数时,这个异步逐步执行.

There are dedicated libraries (like co or task.js), but also many promise libraries have helper functions (Q, Bluebird, when, …) that do this async step-by-step execution for you when you give them a generator function that yields promises.

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 中确实有效,而且一些浏览器(或其开发版本)确实较早地支持生成器语法.

This did work in Node.js since version 4.0, also a few browsers (or their dev editions) did support generator syntax relatively early.

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

However, if you want/need to be backward-compatible you cannot use those without a transpiler. Both generator functions and async functions are supported by the current tooling, see for example the documentation of Babel on generators and async functions.

然后,还有很多其他的编译为 JS 语言致力于简化异步编程.它们通常使用类似于 await 的语法,(例如 Iced CoffeeScript),但还有其他一些具有类似 Haskell 的 do 符号(例如 LatteJs, monadic, PureScriptLispyScript).

And then, there are also many other compile-to-JS languages that are dedicated to easing asynchronous programming. They usually use a syntax similar to await, (e.g. Iced CoffeeScript), but there are also others that feature a Haskell-like do-notation (e.g. LatteJs, monadic, PureScript or LispyScript).

这篇关于如何在 .then() 链中访问先前的承诺结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆