BitlystBitlyst
PostsSeriesTopicsAbout

Bitlyst

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

© 2026 Mohsen Fallahnejad

PostsSeriesTopicsLinksAboutRSSGitHubX
Posts/javascript
Intermediate2 min read

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.

Mohsen Fallahnejad

Mohsen Fallahnejad

Dec 30, 20251 readsDiscuss

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?

The short answer:

JavaScript is single-threaded for executing code, but I/O is handled outside the JS thread.


🧠 What “single-threaded” really means#

  • Only one piece of JavaScript runs at a time.
  • JS does NOT block while waiting for network, timers, or disk.

⚙️ Step-by-step: What happens with Promise.all#

js
await Promise.all([
  fetch("/a"),
  fetch("/b"),
  fetch("/c"),
]);

1️⃣ Requests start immediately#

js
const p1 = fetch("/a");
const p2 = fetch("/b");
const p3 = fetch("/c");
  • Promises are created instantly.
  • Network work starts in the background.
  • JS thread is free.

2️⃣ Network runs outside JS#

  • Browser or Node runtime handles requests.
  • Requests run concurrently.
  • JS thread does nothing during this time.

3️⃣ Promise resolution uses microtasks#

  • When a request finishes, its Promise resolves.
  • .then() callbacks go to the microtask queue.
  • JS executes them one by one.

4️⃣ Promise.all resolves last#

  • Waits for all Promises to resolve.
  • Rejects early if one fails.

🔄 Timeline#

  1. 1

    JS Thread: start A

  2. 2

    start B

  3. 3

    start C

  4. 4

    (free)

  5. 5

    run handlers

then it depends
Network: A request
  1. ↳A done
Network: B request
  1. ↳B done
Network: C request
  1. ↳C done

🧠 Mental Model#

  • JS thread = single chef
  • Network = multiple delivery drivers
  • Promise.all = wait for all deliveries

⚠️ Important note#

Promise.all() does NOT make CPU work parallel.

js
Promise.all([
  heavyTask(),
  heavyTask(),
]);

This still blocks the UI.


🧱 Browser vs Node#

LayerResponsibility
JS ThreadExecutes callbacks
Browser APIs / libuvAsync I/O
PromisesCoordination

✅ Summary#

ConceptMeaning
Single-threadedOne JS execution at a time
ConcurrentMultiple async ops in flight
Promise.allWaits for all async results
Parallel JS❌
Parallel I/O✅

✨ Final takeaway#

JS coordinates work — it doesn’t do it all itself.
Promise.all works because the heavy work happens outside the JS thread.

Filed under#javascript#promises#event loop#async#concurrency

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 ↗
← OlderPromise APIs Compared: all vs race vs any vs allSettledNewer →Why async/await Doesn’t Make JavaScript Code Parallel

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

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.

Dec 30, 20253 min read2

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.

2 min left
Discuss👍 React
👍