Avoid Fail Fast in Promise.all in JavaScript

js logo

The default behavior of Promise.all in JavaScript is to break the full promise execution chain when one of the promises fails.

As you know, Promise.all takes in an array of promises and then returns a promise when all of the promises resolve successfully.

OR

it returns throws an error whenever one of the promises reject.

This is apparent that Promise.all does not handle all the use cases we handle in real life.

Sometimes, you might want to just continue executing the other promises even when one of the promises fail. And, the default behavior of Promise.all will definitely not work for you.

Here’s what we can do to mitigate that.

const promiseHandler = async promise => {
  try {
    const result = await promise;
    return { success: true, data, error: null };
  } catch(error) {
    return { success: false, error, data: null };
  }
};

const runTasks = () => {
  try {
    const task1 = Promise.resolve('task1 successful');
    const task2 = Promise.reject('Oops. We messed up :(');
    const task3 = Promise.resolve('task3 successful');

    const tasks = [task1, task2, task3];
    const promises = tasks.map(promiseHandler);

    return Promise.all(promises);
  } catch(error) {
    console.error(error);

    return null;
  }
};

runTasks()
  .then(console.log)
  .catch(console.error);

This is what the result will look like.

0:
  error: null
  result: "task1 successful"
  success: true
1:
  error: "Oops. We messed up :("
  result: null
  success: false
2:
  error: null
  result: "task3 successful"
  success: true

As you can see, the code actually didn’t throw any error.

Our function resolved successfully with error field as a string with the message:

Oops. We messed up :(

And the other two promises task1 and task3 resolved without an error. The task2 failed, but our code executed gracefully.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.