执行一系列 Javascript 承诺一个接一个地解决

Execute an array of Javascript promises one after one resolved

本文关键字:一个 解决 一系列 承诺 Javascript 执行      更新时间:2023-09-26

我想知道是否有一种方法可以水法执行一系列承诺?即我希望下一个承诺在当前承诺得到解决之前不要开始。

我的测试:

import Promise from 'bluebird'
describe('promises waterfall', () => {
  const result = []
  function doItLater(val, time = 50) => {
    return new Promise(resolve => {
      setTimeout(() => {
        result.push(val)
        resolve(val)
      }, time)
    })
  }
  it('execute promises one after one resolved', done => {
    result.push(1)
    const promiseList = [doItLater('a', 100),doItLater('b', 1),doItLater('c')]
    result.push(2)
    Promise.each(
      promiseList,
      (output) => {
        result.push(output + '-outputted')
      }
    )
      .then(
        () => {
          result.push(3)
          console.log(result)
          expect(result).to.eql([ 1, 2, 'a', 'b', 'c', 'a-outputted', 'b-outputted', 'c-outputted', 3 ])
          done()
        }
      )
  })
})

更新

对不起,如果我把它弄得太混乱了。我在问我怎样才能让我的测试通过。目前我的测试失败 - 实际结果顺序错误:

[ 1,
  2,
  'b',
  'c',
  'a',
  'a-outputted',
  'b-outputted',
  'c-outputted',
  3 ]

当你创建这样的承诺时

[doItLater('a', 100),doItLater('b', 1),doItLater('c')]

它们已经在异步执行。没有办法控制它们的执行顺序。

您可以将Promise.reduce用于您的案例,如下所示

Promise.reduce([['a', 100], ['b', 1], ['c']], function(res, args) {
    return doItLater.apply(null, args).then(function(output) {
        res.push(output + '-outputted');
        return res;
    });
}, result)
.then(function(accumulatedResult) {
    ....
});

现在,我们正在一个接一个地创建承诺,在解决上一个的承诺之后,我们将结果累积在res(实际上是result)。当所有承诺都解决后,accumulatedResult将具有所有值。


注意:强烈建议不要在函数之间共享数据。如果必须这样做,请确保您有令人信服的理由这样做。

// Promisse waterfall pattern
var promises = [1,2,3].map((guid)=>{
    return (param)=> {
      console.log("param", param);
      var id = guid;
      return new Promise(resolve => {
        // resolve in a random amount of time
        setTimeout(function () {
          resolve(id);
        }, (Math.random() * 1.5 | 0) * 1000);
      });
    }
}).reduce(function (acc, curr, index) {
  return acc.then(function (res) {
    return curr(res[index-1]).then(function (result) {
      console.log("result", result);
      res.push(result);
      return res;
    });
  });
}, Promise.resolve([]));
promises.then(console.log);
相关文章: