DEV3 Technologies home

DEV3 Developer Forum

What is the JavaScript event loop and why do promises run before setTimeout?

JavaScript helpSolved0 views
dev3 ·

What does this print and why?

console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');

#javascript#event-loop#promises

0

1 reply

dev3 · Accepted answer

Output: A, D, C, B.

The model

JavaScript runs on one thread with a call stack and two main queues:

  • Macrotask queue: setTimeout, setInterval, I/O callbacks, UI events.
  • Microtask queue: promise reactions (.then, await continuations), queueMicrotask, MutationObserver.

Loop: run the current script to completion, then drain all microtasks, then (browser) maybe render, then take the next macrotask, drain microtasks again, and so on.

Walking through your code

  1. A logs synchronously.
  2. setTimeout schedules a macrotask. Even with 0 ms it waits for the next turn.
  3. Promise.resolve().then queues a microtask.
  4. D logs synchronously. The script ends.
  5. Microtasks drain: C.
  6. Next macrotask: B.

await is microtask based

async function f() {
  console.log(1);
  await null;
  console.log(3);   // runs as a microtask
}
f();
console.log(2);     // 1, 2, 3

Practical consequences

  • A long synchronous loop blocks everything, including rendering and clicks. Split work with setTimeout, requestIdleCallback, scheduler.yield() where supported, or Web Workers.
  • An endless chain of microtasks starves the macrotask queue and freezes the page.
  • Node.js adds phases and process.nextTick (runs before promise microtasks) and setImmediate.

Pitfall: setTimeout(fn, 0) is not instant; browsers clamp nested timers to at least 4 ms and timers in background tabs are throttled.

0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.