【问题标题】:for loop on promise don't follow the good order of outputfor loop on promise 不遵循良好的输出顺序
【发布时间】:2017-05-28 15:32:12
【问题描述】:

我正在尝试在一个承诺中做一个 for 循环,但不幸的是,它的输出不是我所期望的:

我的代码

    var ahaha = function mytestfunction(numb){
    return  new Promise(function(resolve, reject) {
        console.log(numb);
        return resolve('test');
    })
    .then(function(x) {
    z='firststep' + x ;
    console.log(z);
    return z; 
    })
    .then(function(z) {
    console.log(z + 'secondstep');
    return z
    })
    .then(function(z) {
    console.log(z + 'thirdstep')
    });
};

var promises = [];
    for (var i = 1; i <= 2; i++) {
       promises.push(ahaha(i));
    }

Promise.all(promises)    
 .then(function(data){ console.log("everything is finished")});

它返回的是:

1
2
firststeptest
firststeptest
firststeptestsecondstep
firststeptestsecondstep
firststeptestthirdstep
firststeptestthirdstep
everything is finished

但我希望它返回

1
firststeptest
firststeptestsecondstep
firststeptestthirdstep
2
firststeptest
firststeptestsecondstep
firststeptestthirdstep
everything is finished

我不明白为什么承诺没有一个接一个地链接。

请注意,我使用 async.waterfall 成功执行了此操作,但我也想知道如何使用 promises 执行此操作。

非常感谢

【问题讨论】:

    标签: node.js promise ecmascript-6


    【解决方案1】:

    Promise.all() 专门用于当您希望事情并行运行时,它会告诉您什么时候所有事情都完成了,并且它们可以按任意顺序完成。

    有很多不同的方法可以使用 Promise 对事物进行排序。如果您只有两个函数调用,如您的代码所示,您可以手动执行它们:

    ahaha(1).then(result => ahaha(2)).then(data => {
        console.log("everything finished");
    });
    

    或者,使用.reduce()的常见模式:

    [1,2].reduce(p, val => {
        return p.then(() => ahaha(val));
    }, Promise.resolve()).then(data => {
        // everything done here
    });
    

    或者,我最喜欢使用 Bluebird Promise 库:

    Promise.mapSeries([1,2], ahaha).then(result => {
        // everything done here
    });
    

    还有许多其他方案,您可以在这些其他答案中看到:

    How to synchronize a sequence of promises?

    JavaScript: Perform a chain of promises synchronously

    ES6 Promises - something like async.each?

    How can I execute shell commands in sequence?

    Can Promise load multi urls in order?

    【讨论】:

      【解决方案2】:

      Promise.all 用于并行运行 Promise,而不是顺序运行。

      使用流行的 BlueBird 库,您可以使用 reduce,但标准 ES6 中没有等效功能,但您可以这样做:

      promises.reduce(
          (p, next) => p.then(next),
          Promise.resolve()
      ).then(data=>{ console.log("everything is finished")});
      

      【讨论】:

      • Promise.all 不会“运行”承诺,它会聚合它们。您不需要 Bluebird 来减少 - 请参阅其他答案。
      • @Roamer 你读过我的回答吗?我给出了减少承诺并确保按顺序调用它们的解决方案。而我另一个答案之前就这样做了......
      • 那你为什么说“标准 ES6 中没有等价物”呢?
      • 没有等价的功能,有变通办法...改写的更清楚了吗?
      • 而且“Promise.all”仍然“运行”承诺吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 2020-11-05
      • 2015-10-21
      • 1970-01-01
      相关资源
      最近更新 更多