Promise Combinators

Learn how to orchestrate multiple background tasks at the same time. Master Promise.all, Promise.race, and their modern counterparts.

JavaScript7 min readConcept 34 of 62

The Big Four

When you have multiple independent asynchronous tasks, you shouldn't wait for them one by one. You should fire them all off at the same time.

JavaScript provides four static methods on the Promise object - known as combinators - to help you coordinate arrays of Promises.

The 'All or Nothing' Approach

Promise.all([p1, p2]) is the most common combinator. It waits for *every single promise* in the array to fulfill.

If they all succeed, it returns an array of all the results. However, it is an 'all or nothing' deal: if even ONE promise rejects, the entire Promise.all immediately rejects, ignoring the rest.

The Need for Speed

Promise.race([p1, p2]) acts like a literal foot race. It resolves or rejects the moment the *very first* promise settles.

It is commonly used to implement network timeouts (racing a fetch request against a setTimeout that rejects after 5 seconds).

All vs Race

Examine this visual breakdown of how the two most common combinators coordinate multiple background tasks.

Combinator Timelines

// 1. The "All or Nothing" Combinator
await Promise.all([
fetchUser(),
fetchPosts(),
fetchFriends()
]);
// Waits for the slowest to finish
// 2. The "Foot Race" Combinator
await Promise.race([
fetchUser(),
timeoutTimer(5000)
]);
// Resolves/Rejects on the fastest
Promise.all()
Waits for the slowest task
Task 1
Task 2
Task 3
Promise.race()
Takes the fastest task
Task A
Task B
iNotice how Promise.all() is forced to wait for the slowest red task to finish before it resolves, while Promise.race() resolves immediately when the fastest task finishes, ignoring the rest.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1If you pass an array of 5 promises into `Promise.all()`, and the 3rd one rejects after 1 second, what happens?
  2. 2Which combinator is best for implementing a timeout (e.g., aborting a request if it takes longer than 5 seconds)?
  3. 3If you need to fetch data from 3 different APIs, and you want to show whatever data succeeds even if 1 API goes down, which combinator should you use?

Remember this

  • Promise combinators allow you to coordinate arrays of asynchronous tasks.
  • Promise.all waits for ALL to succeed, but fails immediately if ONE rejects.
  • Promise.race takes the VERY FIRST promise to settle, whether it succeeded or failed.
  • Promise.allSettled waits for ALL to finish, never rejecting.
  • Promise.any takes the FIRST success, only rejecting if they ALL fail.

Done with this concept?

Mark it complete to track your progress. No login needed.