Promise Combinators
Promise.all, Promise.race, Promise.allSettled, and Promise.any are static methods that combine multiple Promises. Each has different semantics for handling fulfillment and rejection.
Promise.all = 'everyone must finish the group project or we all fail.' Promise.race = 'first one to the finish line wins.' Promise.any = 'I just need ONE yes from all these job applications.' Promise.allSettled = 'tell me how everyone did, pass or fail.'
Promise.all([p1,p2,p3]) resolves when ALL resolve (returns array of values in order); rejects immediately on first rejection. Promise.race resolves/rejects with the first settled promise. Promise.allSettled waits for all to settle regardless of outcome — returns an array of {status, value|reason} objects. Promise.any resolves with the first fulfillment; rejects with AggregateError if ALL reject. For parallel fetching with no failure tolerance, use all. For timeouts, use race. For best-effort parallel, use allSettled.
Promise.all preserves input order in the results array regardless of resolution order — this is a spec guarantee, not an implementation detail. AggregateError (from Promise.any) is a special error type with an .errors array property containing all individual rejections. In high-concurrency scenarios, creating thousands of Promises simultaneously can cause memory spikes — consider batching with a semaphore pattern or using a library like p-limit. Note that all combinators accept any iterable, not just arrays, enabling use with generators and Sets.
The four combinators handle different failure modes: Promise.all fails fast on first rejection (use for required parallel dependencies), Promise.allSettled always resolves with all outcomes (use for best-effort parallel), Promise.race settles with the first outcome (use for timeouts), Promise.any resolves with first success (use for redundant sources, fallback patterns). Know which to reach for based on your failure tolerance needs.
Promise.all does NOT cancel in-flight promises when one rejects — it merely ignores their results. The other promises continue executing in the background, potentially wasting resources or causing side effects. JavaScript has no native promise cancellation; use AbortController for fetch or a cancellation token pattern for custom async operations.