Working with Promises

JavaScript promises are a handy way to write asynchronous code. It’s common to have multiple promises resolve in parallel or series.

Let’s say you have several functions that return a promise:

function act1() {
  return new Promise((resolve, reject) => {
    // do something that might reject...
    resolve();
  });
}

It’s easy to run these functions in parallel:

Promise.all([act1(), act2(), act3()]).then(() => {
  // all promises fulfilled!
}).catch(err => {
  // something went wrong!
});

But how to run them sequentially? One way is to nest the promises:

act1().then(() => {
  act2().then(() => {
    act3().then(() => {
      // all promises fulfilled!
    });
  });
}).catch(err => {
  // something went wrong!
});

Nesting gets uglify real fast and some consider it an anti-pattern.

My alternative method is to create an array of promise-returning functions and then use Array.reduce to run them one by one:

[act1, act2, act3].reduce(
  (p, fn) => p.then(fn),
  Promise.resolve()
).then(() => {
  // all promises fulfilled!
}).catch(err => {
  // something went wrong!
});

If you’re not familiar with reduce it iterates over an array passing a value between each iteration. Usually you would concatenate a string or extend an object. In this example the value is the next promise. Promise.resolve() is used to start the chain.

Seems like a cleaner solution than nesting?

Here’s a CodePen:

See the Pen Resolve Promises sequentially without nesting by David Bushell (@dbushell) on CodePen.

Matt Hinchliffe shared his library of promise patterns that includes a similar function. I’ve also been experimenting with JavaScript generators and async/await.


Follow @dbushell on Twitter
Return to Blog