BitlystBitlyst
PostsSeriesTopicsAbout

Bitlyst

Short, diagram-first posts on JavaScript, React & Next.js. Follow via RSS or the newsletter.

ยฉ 2026 Mohsen Fallahnejad

PostsSeriesTopicsLinksAboutRSSGitHubX
Posts/javascript
Intermediate3 min read

Promise APIs Compared: all vs race vs any vs allSettled

A practical and conceptual comparison of Promise.all, Promise.race, Promise.any, and Promise.allSettled.

Mohsen Fallahnejad

Mohsen Fallahnejad

Dec 30, 20252 readsDiscuss

Promise APIs Comparison: all vs race vs any vs allSettled

JavaScript provides multiple Promise combinators.
They all start promises concurrently, but they differ in when they resolve/reject and what they return.

Understanding the differences prevents subtle bugs and improves performance.


๐Ÿง  Quick Overview#

APIResolves whenRejects whenTypical use
Promise.allAll promises resolveAny promise rejectsAll-or-nothing
Promise.raceFirst promise settlesFirst promise settlesTimeout / fastest
Promise.anyFirst promise resolvesAll promises rejectFirst success
Promise.allSettledAll promises settleโŒ Never rejectsCollect results

๐Ÿ”น Promise.all#

Behavior#

  • Waits for all promises to resolve
  • Rejects immediately if any promise rejects
js
await Promise.all([
  fetch("/a"),
  fetch("/b"),
  fetch("/c"),
]);

Timeline#

code
A โ”€โ”€โ”€โ”€โ”€โ”
B โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ–บ resolve
C โ”€โ”€โ”€โ”€โ”€โ”˜

When to use#

โœ… You need all results
โŒ One failure should stop everything

Common mistake#

js
await Promise.all(tasks); // crashes if one fails

If partial success is acceptable โ†’ use allSettled.


๐Ÿ”น Promise.race#

Behavior#

  • Settles as soon as the first promise settles
  • That settlement can be resolve or reject
js
await Promise.race([
  fetch("/data"),
  timeout(3000),
]);

Timeline#

code
timeout โ”€โ”€โ–บ reject (wins)
fetch    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ ignored

When to use#

โœ… Timeouts
โœ… First response wins
โŒ Not for โ€œfirst success onlyโ€


๐Ÿ”น Promise.any#

Behavior#

  • Resolves on the first fulfilled promise
  • Rejects only if all promises reject
  • Rejection reason is an AggregateError
js
const result = await Promise.any([
  fetch("/cdn-1"),
  fetch("/cdn-2"),
  fetch("/cdn-3"),
]);

Timeline#

code
cdn-1 โœ–
cdn-2 โœ–
cdn-3 โœ” โ”€โ”€โ–บ resolve

When to use#

โœ… Redundant endpoints
โœ… Fallback strategies
โŒ When failures matter


๐Ÿ”น Promise.allSettled#

Behavior#

  • Waits for all promises to settle
  • Never rejects
  • Returns status for each promise
js
const results = await Promise.allSettled([
  fetch("/a"),
  fetch("/b"),
  fetch("/c"),
]);

Result shape#

js
[
  { status: "fulfilled", value: ... },
  { status: "rejected", reason: ... },
]

Timeline#

code
A โœ”
B โœ–
C โœ” โ”€โ”€โ–บ resolve with report

When to use#

โœ… Logging
โœ… Batch operations
โœ… Partial success allowed


๐Ÿง  Mental Model#

Think of them as rules for waiting:

  • all โ†’ everyone must succeed
  • race โ†’ whoever finishes first decides
  • any โ†’ first success wins
  • allSettled โ†’ everyone reports back

โš ๏ธ Important Notes#

  • All promises start immediately
  • None of these APIs make JS parallel
  • They only coordinate async results

This is still sequential:

js
await a();
await b();

This is concurrent:

js
await Promise.all([a(), b()]);

๐Ÿงช Real-World Use Cases#

ScenarioBest API
Load page dataPromise.all
Add request timeoutPromise.race
Fallback APIPromise.any
Batch processingPromise.allSettled

โŒ Common Pitfalls#

1. Using all when failures are acceptable#

โ†’ causes unnecessary crashes

2. Using race for โ€œfirst successโ€#

โ†’ rejects too early

3. Forgetting AggregateError in any#

js
try {
  await Promise.any(promises);
} catch (e) {
  console.log(e.errors); // list of failures
}

โœ… Summary Table#

APIStops earlyRejectsUse for
allโŒโœ…Must-have-all
raceโœ…โœ…Fastest / timeout
anyโœ…โœ… (all fail)First success
allSettledโŒโŒFull report

โœจ Final Takeaway#

Choose the Promise API based on failure behavior, not speed.
They all run concurrently โ€” the difference is when you stop waiting.

Filed under#javascript#promises#async#event loop

Was this worth your time?

One tap tells me what to write more of.

Mohsen Fallahnejad

Written by

Mohsen Fallahnejad

Frontend engineer explaining JavaScript, React & Next.js internals in posts you can finish over coffee. More about me

X โ†—GitHub โ†—LinkedIn โ†—
โ† OlderAre TypeScript Enums a Good Idea? (Bundle Size & Runtime)Newer โ†’How Promise.all Works in a Single-Threaded JavaScript World

Start the discussion

Questions, corrections, a better approach? I read and reply to every comment.

Read next

Why async/await Doesnโ€™t Make JavaScript Code Parallel

Async/await feels like parallel code, but it isnโ€™t. Hereโ€™s why JavaScript is still single-threaded and how async really works.

Dec 30, 20253 min read1

How Promise.all Works in a Single-Threaded JavaScript World

If JavaScript is single-threaded, how can Promise.all handle multiple requests at the same time? A deep dive into the event loop and async I/O.

Dec 30, 20252 min read1

queueMicrotask Explained: The Smallest Async Queue in JavaScript

What queueMicrotask does, how it differs from Promise.then, and how microtasks really work under the hood.

Dec 31, 20251 min read1

Get new posts in your inbox

No spam. Unsubscribe any time.

3 min left
Discuss๐Ÿ‘ React
๐Ÿ‘