Back to JavaScript
JavaScript
medium
mid

How is Promise.allSettled different from Promise.all, and when would you use it?

`Promise.all` rejects as soon as any input rejects — short-circuits. `Promise.allSettled` always resolves once every input has settled, with an array of `{status, value|reason}` objects. Use `allSettled` for independent best-effort work (dashboard cards, batch operations, analytics) where partial success is meaningful.

3 min read·~5 min to think through

Difference at a glance

js
Promise.all([ok, fail, ok]);
// Rejects with fail's reason as soon as fail rejects.
// Other ok promises still run but their results are lost.

Promise.allSettled([ok, fail, ok]);
// Always resolves once all settle.
// Returns [{status:"fulfilled", value}, {status:"rejected", reason}, {status:"fulfilled", value}]

When to use allSettled

  • Dashboard with N independent cards — one failure shouldn't blank the others.
  • Batch save — return per-item success/failure to show the user partial results.
  • Cache warmup — best-effort, don't fail if a few items don't load.
  • Analytics fan-out — fire to several backends, log failures, don't propagate.
  • Multi-source fetch (CDN mirrors) — record which succeeded.

When to stay with all

  • Atomic compound operations — if any leg fails, the whole thing is invalid.
  • Page load that needs all data to render correctly — fail-fast is right.

Use shape

js
const results = await Promise.allSettled(cardLoaders);

const cards = results.map((r, i) =>
  r.status === "fulfilled"
    ? { ok: true, data: r.value }
    : { ok: false, error: r.reason, retryFn: cardLoaders[i] },
);

Render each card with its own ok/error UI; show retry where it failed.

Related primitives

MethodResolves whenRejects when
Promise.allAll fulfillAny rejects
Promise.allSettledAll settleNever
Promise.raceFirst settles (fulfills or rejects)First rejects
Promise.anyFirst fulfillsAll reject (with AggregateError)

Pre-allSettled workaround

Before allSettled was standard:

js
Promise.all(promises.map((p) => p.then(
  (v) => ({ status: "fulfilled", value: v }),
  (r) => ({ status: "rejected", reason: r }),
)));

Same shape; allSettled is just the standard form.

Interview framing

"Promise.all short-circuits on the first rejection — fine when failure means the whole operation is invalid. Promise.allSettled always resolves with per-promise outcomes — what you want for independent best-effort work like a dashboard with several cards, a batch operation reporting partial success, or analytics fan-out. The shape is { status, value | reason } so you can render success vs failure per item. The pre-2020 polyfill was .map wrapping each promise's outcome."

Follow-up questions

  • What does Promise.any do?
  • When would you use Promise.race?
  • How would you implement allSettled in pre-ES2020 code?

Common mistakes

  • Using Promise.all and losing partial results.
  • Forgetting to inspect status before reading value/reason.

Performance considerations

  • No perf difference. Choice is about correctness / error semantics.

Edge cases

  • Empty input — both resolve immediately ([] result).
  • Thenables (not real Promises) — still work via Promise.resolve coercion.

Real-world examples

  • Dashboard widget loading, batch upload UIs, multi-API aggregation.

Senior engineer discussion

Seniors pick allSettled by default for independent fan-out, then write the per-item render. `Promise.all` is reserved for genuinely atomic operations.

Related questions