DEV Community

Cover image for Effective way to solve Promise Concurrency in Javascript
Mahesh Konne
Mahesh Konne

Posted on • Edited on

Effective way to solve Promise Concurrency in Javascript

As a web developer, sometimes I ran into situations where I need to make concurrent API calls and my go to solution was Promise.all()

yes, It solves the problem. But most of the developers do not know(or don't care?) about the problem it comes with.. "Error handling"

Okay, What's the Problem?

Promise.all() takes an iterable of promises as input and returns a single Promise. This returned promise fulfills when all of the input's promises fulfill, with an array of the fulfillment values. It rejects when any of the input's promises rejects, with this first rejection reason.

Here's an example code

const user = await fetchUser();
const posts = await fetchPosts();
Enter fullscreen mode Exit fullscreen mode

above two API's are independent to each other. And to optimize the performance, we can call them concurrently

const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
Enter fullscreen mode Exit fullscreen mode

Awesome. It looks good now. The next step we need to take care of while working with Asynchronous code is "Error Handling"

let's catch the errors..

try {
    const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
} catch (e) {
    // Handle the error
    console.log(`Something went wrong: ${e}`)
}
Enter fullscreen mode Exit fullscreen mode

even though it looks good, there's a big problem here. The returned promise rejects when any of the input's promises rejects.. meaning If both the API calls fail, we can only be able to catch the first rejection reason here..

how to fix this? 🤔

The answer is Promise.allSettled()

The Promise.allSettled() takes an iterable of promises as input and returns a single Promise. This returned promise fulfills when all of the input's promises settle, with an array of objects that describe the outcome of each promise.

const [user, posts] = await Promise.allSettled([fetchUser(), fetchPosts()]);

if(user.status === "rejected") {
    // handle user error
}

if(posts.status === "rejected") {
    // handle posts error
}
Enter fullscreen mode Exit fullscreen mode

Bang!🎉 It perfectly serves our needs.

Here are the key takeways 📝:

  • Promise.all() will reject as soon as one of the Promises in the array rejects.
  • Promise.allSettled() will resolve once all Promises in the array have either resolved or rejected.

If you found this useful, don't forget to follow me for more JS stuff. Cheers! 🥂

Top comments (0)