Q18 of 40 · JavaScript

What is the difference between `Promise.all()`, `Promise.allSettled()`, `Promise.race()`, and `Promise.any()`?

JavaScriptMidjavascriptpromisespromise-combinatorsasyncparallel

Short answer

Short answer: `Promise.all` resolves when all resolve, fails fast on first rejection. `Promise.allSettled` always resolves with outcome objects for every promise. `Promise.race` settles with the first settled promise. `Promise.any` resolves with the first fulfillment, rejects only if all reject.

Detail

JavaScript provides four combinators for running multiple Promises in parallel with different failure semantics.

Promise.all(promises): Resolves when every promise resolves; result is an array in the same order. Rejects immediately (short-circuits) when any promise rejects. Use when all results are required and any failure should stop the operation — like setting up all test fixtures.

Promise.allSettled(promises): Always resolves with an array of outcome objects: { status: 'fulfilled', value } or { status: 'rejected', reason }. Use when you need all results regardless of individual failures — batch API calls, parallel cleanup where partial failure is acceptable.

Promise.race(promises): Resolves or rejects with the outcome of the first promise to settle. Use for timeout patterns: race a real request against a delay that rejects.

Promise.any(promises): Resolves with the first fulfilled promise. Rejects with an AggregateError only when all promises reject. Use for "first successful response wins" scenarios (e.g., fastest mirror).

// EXAMPLE

const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.reject(new Error("boom"));

// all — short-circuits on rejection
await Promise.all([p1, p2, p3])
  .catch(e => console.error(e.message)); // "boom"

// allSettled — collects everything
const results = await Promise.allSettled([p1, p2, p3]);
results.forEach(r => {
  if (r.status === "fulfilled") console.log("ok:", r.value);
  else console.log("err:", r.reason.message);
});

// Timeout pattern with race
const withTimeout = (promise, ms) =>
  Promise.race([
    promise,
    new Promise((_, reject) =>
      setTimeout(() => reject(new Error("timeout")), ms)
    ),
  ]);

// WHAT INTERVIEWERS LOOK FOR

Clear contrast between all (fail-fast) vs allSettled (always resolves). Knowing when each is appropriate. Bonus: the timeout pattern with race, or mentioning allSettled for test teardown where some cleanups may fail.

// COMMON PITFALL

Using Promise.all for independent API calls where one failure should not block others. Also: forgetting to check `.status` on allSettled results — accessing `.value` on a rejected outcome gives `undefined`.