Handling an Array of Promises

A very common situation is having to make many asynchronous calls.

There are two ways that we can wait for those to happen:

  • All at once / without concern for order
  • In the order of the array

There's a few ways that we can very easily handle these with the in built native promise methods.

Our Array and our Mission

The situation is simple: we want to make a network request to get details about Christopher Nolan films.

With that said, our array is simple:

let movies = [  
  "Batman Begins",
  "The Dark Knight",
  "The Dark Knight Rises",
  "Inception"
]

We'll use a method, requestMovieDetails(title) which returns a Promise.

We're going to use a series of Promise and Array methods to make our life easy.

All at once / without concern for order

The easiest case is waiting for all the results:

let moviePromises = movies.map(title => requestMovieDetails(title));

let allMoviesComplete = Promise.all(moviePromises);

allMoviesComplete.then((movieDetailArray) => {  
  // This will occur after all have completed
}).catch(e => {
  // This will occur if any have failed!
});

In this one, we leverage two things:

  • Promise.all will wait for all promises to exit the pending status
  • Since we map and return our promise, we start the download the second we map it.

In the order of the array

Leveraging the order of the array is a little trickier, but not particularly bad.

The first thing we must do is make a promise that is already resolved, using Promise.resolve to chain off of. Then we need to reduce the array and chain off each operation.

let dummyPromise = Promise.resolve();

movies.reduce((currentChain, newMovie) => {  
  // currentChain is our entire promise chain thus far
  // newEntry is our string, the movie entry
  return currentChain.then((lastMovieDetails) => {
    console.log(lastMovieDetails);
    // This will be the movie details immediately before
    // It could also be the dummyPromise result, so remember to check for undefined.

    return requestMovieDetails(newMovie);
  });
}, dummyPromise);

This will iterate through the array and compose a giant promise chain that will go through one at a time in order.