Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Promises: Chain same promise n times, then do something else

I have a promise-returning function that does some async stuff, let's call it functionToRepeat().

I am trying to write the function repeatFunction(amount) , so that it will start the promise, wait for completion, start it again, wait for completion, and so on a given amount of times. This repeatFunction(amount) should also be thenable, so that I can chain other stuff after it's been executed.

Here is my attempt:

function functionToRepeat(){
  let action = new Promise(function(resolve,reject){
    setTimeout(function(){
      console.log("resolved!");
      resolve()}
    ,1000);
  })
  return action
}

function repeatFunction(amount) {
  if(amount==0){
    return Promise.resolve();
  }
  return functionToRepeat().then(function(){
    repeatFunction(amount-1);
  });
}

repeatFunction(5).then(function(){
 console.log("DONE!");
})

This successfully chains my promises (or so it seams, I get one "resolved!" per second in the console). However the .then() I try to chain after my repeatFunction(5) happens after the 1st promise ends, not after all 5 have ended!

So in my console I get:

resolved! DONE! resolved! resolved! resolved! resolved!

What am I doing wrong and what should I change?

like image 534
Gloomy Avatar asked Dec 07 '16 15:12

Gloomy


People also ask

What happens if you resolve a promise multiple times?

It is not safe to resolve/reject promise multiple times. It is basically a bug, that is hard to catch, becasue it can be not always reproducible.

How do you handle multiple promises?

In this approach, we will use Promise. all() method which takes all promises in a single array as its input. As a result, this method executes all the promises in itself and returns a new single promise in which the values of all the other promises are combined together.

Can promises be chained?

Example 2: Chaining the Promise with then() Promise resolved You can call multiple functions this way. In the above program, the then() method is used to chain the functions to the promise. The then() method is called when the promise is resolved successfully. You can chain multiple then() methods with the promise.

Can a promise be awaited multiple times?

The implication of this is that promises can be used to memoize async computations. If you consume a promise whose result will be needed again later: consider holding on to the promise instead of its result! It's fine to await a promise twice, if you're happy to yield twice.


1 Answers

How about simply:

function repeat(func, times) {
  var promise = Promise.resolve();
  while (times-- > 0) promise = promise.then(func);
  return promise;
}

When tested with this:

function oneSecond() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log("tick");
      resolve();
    }, 1000);
  });
}

repeat(oneSecond, 5).then(function () {
    console.log("done");
});

this output is produced over 5 seconds:

tick
tick
tick
tick
tick
done
like image 85
Tomalak Avatar answered Nov 10 '22 09:11

Tomalak