Promise.all vs Promise.race: What Is the Difference Between These JavaScript Methods?

Promise.all waits for all promises to complete and returns an array of results, while Promise.race returns the result of the first promise that settles, whether it fulfills or rejects.

The h5bp/Front-end-Developer-Interview-Questions repository includes this comparison as a core concept for front-end interviews. Understanding the difference between Promise.all and Promise.race helps developers choose the right tool for coordinating multiple asynchronous operations in JavaScript.

Core Functional Differences

Both Promise.all and Promise.race are static methods on the native Promise constructor, but they follow opposite coordination strategies:

  • Promise.all: Waits for every promise in the iterable to settle. It fulfills with an array of all values in original order, or rejects immediately if any single promise rejects.
  • Promise.race: Resolves or rejects as soon as the first promise settles, using that promise's value or reason. Later settlements are ignored.

The key distinction lies in their completion criteria: all requires 100% success for fulfillment, while race is a competition where speed determines the outcome.

How Promise.all Works Under the Hood

When you invoke Promise.all, the JavaScript engine creates a new promise and attaches handlers to each input promise. Internally, it maintains a counter tracking how many promises have fulfilled. Each fulfillment stores its value at the corresponding index in a results array. Only when the counter matches the total number of promises does the returned promise resolve with the collected array.

If any input promise rejects, the entire operation short-circuits immediately. The returned promise rejects with that reason, and the remaining promises are ignored regardless of whether they eventually fulfill or reject.

Common Use Case for Promise.all

Use Promise.all when you need all results before continuing, such as loading multiple resources in parallel:

const urls = [
  '/api/users',
  '/api/posts',
  '/api/comments'
];

Promise.all(urls.map(url => fetch(url).then(r => r.json())))
  .then(([users, posts, comments]) => {
    console.log('All data loaded', { users, posts, comments });
  })
  .catch(err => console.error('One request failed', err));

How Promise.race Works Under the Hood

Promise.race registers a single resolution/rejection handler on each input promise. The first handler that executes settles the returned promise permanently. All other handlers effectively become no-ops, meaning you will never see the results of slower promises regardless of whether they fulfill or reject later.

This makes race ideal for timeout patterns or selecting the fastest response from multiple sources.

Common Use Cases for Promise.race

Implementing request timeouts:

const fetchWithTimeout = (url, ms) => {
  const timeout = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), ms)
  );
  return Promise.race([fetch(url), timeout]);
};

fetchWithTimeout('/api/slow-endpoint', 2000)
  .then(resp => resp.json())
  .then(data => console.log('Got data before timeout', data))
  .catch(err => console.error('Failed or timed out', err));

Selecting the fastest mirror:

const mirrorA = fetch('https://mirror-a.example.com/file');
const mirrorB = fetch('https://mirror-b.example.com/file');

Promise.race([mirrorA, mirrorB])
  .then(resp => resp.blob())
  .then(blob => console.log('Got file from fastest mirror', blob))
  .catch(err => console.error('Both mirrors failed', err));

Repository Context and Interview Preparation

According to the h5bp/Front-end-Developer-Interview-Questions source code, these concepts appear in several key locations:

  • src/questions/javascript-questions.md: Contains foundational promise questions that lead into discussions about Promise.all and Promise.race.
  • src/questions/coding-questions.md: Includes practical coding challenges where knowing the difference between these methods helps solve asynchronous coordination problems.
  • README.md: Provides the project overview linking to these question sets as essential interview preparation material.

Interviewers often ask about these methods to assess whether candidates understand JavaScript's concurrency model and can select appropriate patterns for parallel versus competitive execution.

Summary

  • Promise.all fulfills only when every promise succeeds, returning an ordered array of results, and fails fast on the first rejection.
  • Promise.race settles immediately when any promise settles, making it perfect for timeouts and selecting the fastest response.
  • Both methods are static on the Promise constructor and defined in the ECMAScript specification (Sections 25.6.4 and 25.6.5).
  • Use all for aggregating parallel data fetching; use race for implementing timeouts or redundant request strategies.

Frequently Asked Questions

Can Promise.all succeed if some promises reject?

No. Promise.all implements a "fast-fail" approach. If any promise in the iterable rejects, the returned promise immediately rejects with that reason, regardless of whether other promises eventually fulfill. Only Promise.allSettled (a separate method) allows you to wait for all promises regardless of their individual outcomes.

What happens to losing promises in Promise.race after the first settles?

The remaining promises continue executing in the background, but their results are discarded. The race method does not cancel the underlying operations. If you need to cancel or clean up resources from the slower promises, you must implement additional logic using AbortController or similar cancellation patterns.

Does Promise.all preserve the order of results?

Yes. The fulfillment values appear in the same order as the input promises, even if they settle out of order. For example, if promise at index 2 completes before promise at index 0, Promise.all still places the results at their original indices in the final array.

Which method should I use for implementing a fetch timeout?

Use Promise.race. Create a timeout promise that rejects after a delay using setTimeout, then race it against your fetch request. Whichever settles first determines the outcome. If the fetch completes first, you get the data; if the timeout fires first, you get a timeout error.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →