Ben Davis Ben Davis - 2 months ago 7
Javascript Question

How do you synchronously resolve a chain of es6 promises?

I have a function from a library that returns a promise. I need to run this function multiple times, but each iteration must wait until the previous task is done.

My assumption was that I could do this:

promiseReturner(1)
.then(promiseReturner(2)
.then(promiseReturner(3)
.then(...)


Which could be simplified using a loop:

var p = Promise.resolve();
for (var i=1; i<=10; i++) {
p = p.then(promiseReturner(i));
}


However, when I do this each promise in the chain is executed at the same time, instead of one after the other as
.then()
seems to imply. Clearly I'm missing something fundamental about promises -- but after reading several tutorials and blog posts I'm still lost.

Here's a codepen I wrote up to demonstrate my attempt.

Answer

Your "non-loop" solution shouldn't work either. You have to pass a function to .then, not a promise:

var p = Promise.resolve();
for (var i=1; i<=10; i++) {
  (function(i) {
      p = p.then(function() {
          return promiseReturner(i);
      });
  }(i));
}

If that function returns a promise, then you get that chaining effect.

More info about promises on MDN.


Can be simplified with let (and arrow functions):

var p = Promise.resolve();
for (let i=1; i<=10; i++) {
    p = p.then(() => promiseReturner(i));
}

Or .bind (which is ES5):

var p = Promise.resolve();
for (var i=1; i<=10; i++) {
    p = p.then(promiseReturner.bind(null, i));
}