如何动态地向promises链添加新的承诺

时间:2018-02-28 13:06:03

标签: javascript promise

我想创建promises链,然后根据需要动态添加尽可能多的promises。这些添加可能在一些循环中具有动态步数,因此我不能使用链接,如.then()。then()。然后...代码bellow工作不正常,但你会得到这个想法。结果应该是一个控制台在3,4和5秒内记录了3000,4000,5000个数字,但实际上并不是这样。有什么想法吗?

let launchChain = function(delay)
{
  return new Promise((resolve: Function, reject: Function) => {
    setTimeout(() => {
      console.log(delay);
      resolve();
    }, delay)
  })
}

let chain = launchChain(3000);

chain.then(function () {
  return launchChain(4000);
})

chain.then(function () {
  return launchChain(5000);
})

3 个答案:

答案 0 :(得分:2)

function run(delay){
    let chain = launchChain(delay);
    chain.then(function() {
        run(delay+1000);
    });
}


run(3000);

答案 1 :(得分:1)

使用了reducesite

var delays = [0, 1000, 2000, 3000, 4000];

function workMyCollection(arr) {
  return arr.reduce(function(promise, item) {
    return promise.then(function() {
      return launchChain(item);
    });
    // uses this orignal promise to start the chaining.
  }, Promise.resolve());
}

function launchChain(delay) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log(delay);
      resolve();
    }, delay);
  });
}

workMyCollection(delays);
[编辑]:另一种方式

var delays = [0, 1000, 2000, 3000, 4000];
var currentPromise = Promise.resolve();

for (let i = 0; i < delays.length; i++) {
  // let makes i block scope .. var would not have done that
  currentPromise = currentPromise.then(function() {
    return launchChain(delays[i]);
  });
}

function launchChain(delay) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log(delay);
      resolve();
    }, delay);
  });
}

请告诉我这是否适合你:) 感谢这个问题,我学到了很多东西!

答案 2 :(得分:0)

感谢sinhavartika!有用!但我实际上是从这里开始的 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce 并改变了一点,现在我以下列方式在我的项目中使用它:

  /**
   * Runs promises from promise array in chained manner
   *
   * @param {array} arr - promise arr
   * @return {Object} promise object
   */
  function runPromiseInSequense(arr) {
    return arr.reduce((promiseChain, currentPromise) => {
      return promiseChain.then((chainedResult) => {
        return currentPromise(chainedResult)
          .then((res) => res)
      })
    }, Promise.resolve());
  }

  var promiseArr = [];

  function addToChain(delay)
  {
    promiseArr.push(function (delay) {
      return new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log(delay);
            resolve();
          }, delay)
      });
    }.bind(this, delay))
  }

  addToChain(1000);
  addToChain(2000);
  addToChain(3000);
  addToChain(4000);

  runPromiseInSequense(promiseArr);