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:
Matt Hinchliffe shared his library of promise patterns that includes a similar function. I’ve also been experimenting with JavaScript generators and async/await.