Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay between promises when using Promise.all

Is there a way to delay the evaluation of an array of promises using Promise.all()?

Does it make sense to manually add a delay function to the end of each promise before adding them to the array?

Promise.all([p1,p2,p3]).then(res => console.log(res))

I would like to add a delay because my server can't handle too many requests at once.

like image 578
timothyylim Avatar asked Nov 21 '17 18:11

timothyylim


People also ask

Does promise all wait for all promises?

Promise.all waits for all fulfillments (or the first rejection).

How do I add a delay in promise all?

all . In order to do this, promises should be initially created to produce a delay: const delayIncrement = 500; let delay = 0; const p1 = new Promise(resolve => setTimeout(resolve, delay)). then(() => fetch(...)); delay += delayIncrement; const p2 = new Promise(resolve => setTimeout(resolve, delay)).

What if one promise fails in promise all?

In other words, if any promise fails to get executed, then Promise. all() method will return an error and it will not take into the account whether other promises are successfully fulfilled or not.

Does promise all run promises in parallel?

As you can see, Promise. all executes code concurrently, but what is parallel execution? JavaScript is single-threaded and can only perform a single chunk of work at a time, so parallel execution is not possible with JavaScript, except for some circumstances such as web workers.


1 Answers

Yes, you can delay promises using Promise.all to create staggered execution and it's quite easy to do:

// Promise.all() with delays for each promise
let tasks = [];
for (let i = 0; i < 10; i++) {
  const delay = 500 * i;
  tasks.push(new Promise(async function(resolve) {
    // the timer/delay
    await new Promise(res => setTimeout(res, delay));

    // the promise you want delayed
    // (for example):
    // let result = await axios.get(...);
    let result = await new Promise(r => {
      console.log("I'm the delayed promise...maybe an API call!");
      r(delay); //result is delay ms for demo purposes
    });

    //resolve outer/original promise with result
    resolve(result);
  }));
}

let results = Promise.all(tasks).then(results => {
  console.log('results: ' + results);
});

You can run it here too.

Rather than a delay between the chain, which can be done with .then() as shown in other answers, this is a delay that differs for each Promise so that when you call Promise.all() they will be staggered. This is useful when, say, you are calling an API with a rate limit that you'd breach by firing all the calls in parallel.

Peace

like image 107
GoForth Avatar answered Sep 30 '22 07:09

GoForth