为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

汪汪一只猫 2019-05-22 14:51:22
如何在.then()链中访问先前的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?    });}
查看完整描述

4 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

打破链条

当您需要访问链中的中间值时,您应该将链条拆分成您需要的那些单件。而不是附加一个回调并以某种方式尝试多次使用其参数,将多个回调附加到同一个承诺 - 无论您需要结果值。不要忘记,承诺只代表(代理)未来的价值!接下来,在线性链中从另一个派生一个承诺,使用库提供给您的promise组合器来构建结果值。

这将导致非常简单的控制流程,清晰的功能组合,因此易于模块化。

function getExample() {

    var a = promiseA(…);

    var b = a.then(function(resultA) {

        // some processing

        return promiseB(…);

    });

    return Promise.all([a, b]).then(function([resultA, resultB]) {

        // more processing

        return // something using both resultA and resultB

    });

}

Promise.all在ES5中只有ES6可用的回调中的参数解构代替,在ES5中,then调用将被许多promise库(QBluebirdwhen,...)提供的漂亮的辅助方法取代:.spread(function(resultA, resultB) { …

Bluebird还具有专用join功能,可以用更简单(更高效)的构造替换Promise.allspread组合:

…return Promise.join(a, b, function(resultA, resultB) { … });


查看完整回答
反对 回复 2019-05-22
?
德玛西亚99

TA贡献1770条经验 获得超3个赞

同步检查

将promises-for-later-needed-values分配给变量,然后通过同步检查获取它们的值。该示例使用bluebird的.value()方法,但许多库提供类似的方法。

function getExample() {
    var a = promiseA(…);

    return a.then(function() {
        // some processing
        return promiseB(…);
    }).then(function(resultB) {
        // a is guaranteed to be fulfilled here so we can just retrieve its
        // value synchronously
        var aValue = a.value();
    });}

这可以用于任意数量的值:

function getExample() {
    var a = promiseA(…);

    var b = a.then(function() {
        return promiseB(…)
    });

    var c = b.then(function() {
        return promiseC(…);
    });

    var d = c.then(function() {
        return promiseD(…);
    });

    return d.then(function() {
        return a.value() + b.value() + c.value() + d.value();
    });}


查看完整回答
反对 回复 2019-05-22
?
湖上湖

TA贡献2003条经验 获得超2个赞

嵌套(和)闭包

使用闭包来维护变量的范围(在我们的例子中,成功的回调函数参数)是自然的JavaScript解决方案。有了promises,我们可以任意地嵌套和压缩 .then()回调 - 它们在语义上是等价的,除了内部的范围。

function getExample() {
    return promiseA(…).then(function(resultA) {
        // some processing
        return promiseB(…).then(function(resultB) {
            // more processing
            return // something using both resultA and resultB;
        });
    });}

当然,这是建立一个缩进金字塔。如果缩进变得太大,你仍然可以使用旧工具来对抗厄运金字塔:模块化,使用额外的命名函数,并在不再需要变量时立即压缩承诺链。
理论上,你总是可以避免两个以上的嵌套级别(通过使所有闭包显式化),在实践中使用尽可能多的合理。

function getExample() {
    // preprocessing
    return promiseA(…).then(makeAhandler(…));}function makeAhandler(…)
    return function(resultA) {
        // some processing
        return promiseB(…).then(makeBhandler(resultA, …));
    };}function makeBhandler(resultA, …) {
    return function(resultB) {
        // more processing
        return // anything that uses the variables in scope
    };}

您还可以使用辅助功能对于这种局部的应用,如_.partial下划线 / lodash本地.bind()方法,进一步减少缩进:

function getExample() {
    // preprocessing
    return promiseA(…).then(handlerA);}function handlerA(resultA) {
    // some processing
    return promiseB(…).then(handlerB.bind(null, resultA));}function handlerB(resultA, resultB) {
    // more processing
    return // anything that uses resultA and resultB}


查看完整回答
反对 回复 2019-05-22
  • 4 回答
  • 0 关注
  • 1331 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信