Home/Learn/JavaScript & TypeScript/The Event Loop — One Thread, No Blocking

The Event Loop — One Thread, No Blocking

Intermediate
Async

JavaScript runs your code on a single thread. Asynchronous work is handed to the runtime and its callback is queued, so nothing runs concurrently with your code — it runs after it.

Overview

This is the model that has to replace your threading instincts. In Java, concurrency means threads and you protect shared state with locks. In JavaScript there is one thread running your code, so there are no data races and no locks — but there is also nothing else to run your code while it is busy, which means a slow synchronous loop freezes the entire page. Async work does not happen in parallel with your function; it happens after your function and everything else on the stack has finished. Getting this right explains setTimeout(fn, 0) firing late, why await does not block anything else, and why a heavy computation makes the UI unresponsive.

Stack, Queues, Loop

The call stack runs your code. When it empties, the loop takes the next callback. Microtasks — promises — always drain completely before the next macrotask.

Why the output is 1, 4, 3, 2
console.log('1')                          // sync

setTimeout(() => console.log('2'), 0)     // macrotask queue

Promise.resolve().then(() => console.log('3'))  // microtask queue

console.log('4')                          // sync

// Output: 1, 4, 3, 2
//
// 1 and 4 run on the stack, in order.
// The stack empties.
// ALL microtasks drain: 3.
// Then one macrotask: 2.

// This is why setTimeout(fn, 0) is not "immediately":
// it is "after the current stack and all pending promises".

Microtasks Starve Macrotasks

Microtasks drain fully before any macrotask runs. A promise chain that keeps adding microtasks blocks timers and rendering indefinitely.

Microtask priority, and starvation
// This never lets a timer run:
function loop() { Promise.resolve().then(loop) }
loop()
setTimeout(() => console.log('never'), 0)

// Ordering with both kinds:
setTimeout(() => console.log('timeout'))
Promise.resolve().then(() => console.log('promise'))
queueMicrotask(() => console.log('microtask'))
// promise, microtask, timeout

// Node adds process.nextTick, which jumps ahead of promises:
process.nextTick(() => console.log('tick'))   // before promise callbacks

Blocking the Thread

The practical consequence: any long synchronous operation freezes everything, including rendering and clicks.

async does not mean parallel
// Freezes the browser for the whole loop — no paint, no clicks
function sumTo(n) {
  let total = 0
  for (let i = 0; i < n; i++) total += i
  return total
}
sumTo(1e10)

// Async does NOT fix this — await yields, it does not parallelise:
async function stillFrozen() {
  await null
  sumTo(1e10)        // still blocks: it is synchronous work
}

// Real fixes: a Web Worker (another thread), or chunk the work
// and yield between chunks so the loop can paint.
async function chunked(items) {
  for (let i = 0; i < items.length; i++) {
    process(items[i])
    if (i % 500 === 0) await new Promise(r => setTimeout(r))
  }
}

Key Points to Remember

  • 1One thread runs your code — no data races, no locks, but also nothing else runs while you are busy
  • 2Microtasks (promises) drain completely before the next macrotask (timers, I/O callbacks)
  • 3setTimeout(fn, 0) means "after the current stack and all pending microtasks", not "now"
  • 4async/await yields control; it does not move work to another thread — CPU-bound code still blocks
  • 5For genuinely parallel CPU work you need a Web Worker; otherwise chunk and yield so the page can paint

Interview Questions

Sign in to ask Aria
1

What does this print: console.log(1); setTimeout(()=>console.log(2)); Promise.resolve().then(()=>console.log(3)); console.log(4)?

Medium
2

What is the difference between a microtask and a macrotask?

Medium
3

Does making a function async make it run in parallel? Why or why not?

Medium

Ask Aria about The Event Loop — One Thread, No Blocking

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…