Explain Promises in Node — states, chaining, and the combinators (all/race/allSettled/any).

3 minintermediatenodejspromisespromise-allcombinatorsasync

Quick Answer

A Promise represents a future value in one of three states: pending, fulfilled, or rejected. `.then/.catch/.finally` chain transformations and errors. Combinators run multiple promises together: `all` (fail-fast, all results), `allSettled` (never rejects), `race` (first to settle), `any` (first to fulfill).

Detailed Answer

Answer:

States: a Promise is pending, then settles to fulfilled (with a value) or rejected (with a reason). Once settled it never changes.

Chaining: each .then returns a new promise, so you can transform values and funnel all errors to a single .catch:

fetchUser(id)
  .then(user => fetchPosts(user.id))
  .then(posts => render(posts))
  .catch(err => handle(err))   // catches any rejection above
  .finally(() => stopSpinner());

Combinators:

MethodSettles whenResultUse case
Promise.allall fulfilled, or first rejectionarray of values / first errorparallel work, all required
Promise.allSettledall settledarray of {status, value/reason}independent tasks, want every outcome
Promise.racefirst to settle (either way)that value/reasontimeouts, fastest wins
Promise.anyfirst fulfillment, or all rejectedfirst value / AggregateErrorfallbacks/redundancy
// Fetch three resources in parallel; fail if any fails
const [a, b, c] = await Promise.all([getA(), getB(), getC()]);

// Add a timeout to any promise
const result = await Promise.race([
  doWork(),
  new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), 5000)),
]);

Gotchas:

  • Promise.all is fail-fast: one rejection rejects the whole thing (the others still run but their results are discarded). Use allSettled when you need every outcome.
  • Always attach a .catch (or wrap await in try/catch) — an unhandled rejection can crash the process.