简体   繁体   中英

How to dynamically add new promise to the promises chain

I want to create promises chain and then dynamically add as many promises to it as it's needed. These additions could be in some cycle with dynamic number of steps so that I can't use chain like .then().then().then... Code bellow works improperly but you'll get the idea. Result should be a console logged 3000, 4000, 5000 numbers in 3, 4 and 5 seconds consequently but actually doesn't work that way. Any ideas?

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);
})
function run(delay){
    let chain = launchChain(delay);
    chain.then(function() {
        run(delay+1000);
    });
}


run(3000);

So used reduce and this site

 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); 
[EDIT] : Another way

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

Do let me know if this worked for you :) thanks to this question I learned a lot!

Thanks sinhavartika! It works! But I actually took example from here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce and changed it a bit and now I use it in my project in the following way:

  /**
   * 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM