Promise.all vs allSettled vs race vs any (JavaScript Promise Combinators)

HighHardJavascript
Preparing for interviews?

Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.

Quick Answer

Promise combinators coordinate multiple async operations. all fails fast, allSettled always returns results, race resolves/rejects with the first settled promise, and any resolves with the first fulfilled promise (or rejects with AggregateError if all reject). Know the exact output shapes and failure behavior for interviews.

Answer

The mental model

All four take an iterable of promises (values are auto-wrapped via Promise.resolve). The key differences are:

1) What “finishes” the combinator (first failure? first settle? first success? all done?)
2) What it returns (values only vs per-promise status objects)
3) How errors behave (fail-fast vs aggregate)

Also: these combinators do not cancel the other promises; they just decide what result to produce.

Combinator

Resolves when...

Rejects when...

Resolved value shape

Typical use

Promise.all

All promises fulfill

Any promise rejects (fail-fast)

Array of fulfillment values (in input order)

All-or-nothing dependencies (e.g., load config + user + flags)

Promise.allSettled

All promises settle (fulfilled or rejected)

Never (unless input iteration throws)

Array of result objects: {status:'fulfilled', value} or {status:'rejected', reason}

Collect outcomes (e.g., show partial results, log failures)

Promise.race

First promise settles and it fulfills

First promise settles and it rejects

The first settled value (or rejection reason)

Timeouts / “first response wins”

Promise.any

First promise fulfills

All promises reject

The first fulfilled value; rejects with AggregateError

Fallbacks (e.g., first successful endpoint/CDN)

Cheat sheet: finish condition + error semantics.

Minimal examples

JAVASCRIPT
const ok1 = Promise.resolve('A');
const ok2 = Promise.resolve('B');
const bad = Promise.reject(new Error('X'));

// 1) all: fails fast on first rejection
await Promise.all([ok1, ok2]);          // -> ['A', 'B']
await Promise.all([ok1, bad, ok2]);     // -> rejects with Error('X')

// 2) allSettled: always returns status objects
await Promise.allSettled([ok1, bad, ok2]);
// -> [
//   { status: 'fulfilled', value: 'A' },
//   { status: 'rejected', reason: Error('X') },
//   { status: 'fulfilled', value: 'B' }
// ]

// 3) race: first settle wins (could be reject)
await Promise.race([bad, ok1]);         // -> rejects (bad settles first)
await Promise.race([ok1, bad]);         // -> 'A'

// 4) any: first fulfillment wins (ignores rejects until all reject)
await Promise.any([bad, ok2]);          // -> 'B'
await Promise.any([bad, Promise.reject('Y')]);
// -> rejects with AggregateError (contains all reasons)
                  

Important details interviewers look for

1) Input order: all and allSettled keep the output array aligned with the input order, not completion order.

2) Fail-fast vs keep-going:

  • all rejects as soon as one rejects.
  • allSettled waits for all.
  • race settles on the first settled promise (resolve or reject).
  • any resolves on the first fulfillment; only rejects if everything rejects.

3) No cancellation: Promise.all rejecting does not stop the other operations. If you need cancellation, you need explicit support (e.g., AbortController for fetch).

4) AggregateError: Promise.any rejects with an AggregateError, which bundles all rejection reasons (often via error.errors in many runtimes).

Classic pattern: timeout with race

Use race to bound time. But remember: the original async work continues unless it’s cancellable.

JAVASCRIPT
function timeout(ms) {
  return new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), ms)
  );
}

async function fetchWithTimeout(url, ms, signal) {
  // Prefer real cancellation (AbortController) when possible.
  const fetchPromise = fetch(url, { signal });
  return Promise.race([fetchPromise, timeout(ms)]);
}
                  

Classic pattern: first successful response with any

JAVASCRIPT
async function firstHealthy(urls) {
  return Promise.any(
    urls.map(async (u) => {
      const r = await fetch(u);
      if (!r.ok) throw new Error(`${u} -> ${r.status}`);
      return r;
    })
  );
}

// If all endpoints fail -> AggregateError
                  

One-liners to memorize

  • all: “All succeed or I fail fast.”
  • allSettled: “Tell me how each one ended.”
  • race: “First one to settle decides.”
  • any: “First success wins; otherwise aggregate failure.”
Similar questions
Guides
13 / 61