QuestionsJavaScript

Event loop: micro vs macro tasks

Event Loop / AsyncMediumJavaScript

What does this log and why? console.log(1); setTimeout(cb2); Promise.resolve().then(cb3); console.log(4);

What it tests

Whether you know the microtask queue drains before the next macrotask.

Approach & answer

Logs 1, 4, 3, 2. Synchronous code runs first (1, 4). Then the event loop drains ALL microtasks (Promise callbacks) before any macrotask (setTimeout) — so 3 before 2. The rule: after each task, the engine empties the entire microtask queue before rendering or picking up the next timer. The full model: the call stack runs synchronous code to completion; then, on each tick, the loop runs one macrotask (a timer callback, an I/O callback, a UI event), then drains the microtask queue COMPLETELY — including any microtasks those microtasks schedule — before the browser gets a chance to render and before the next macrotask. Microtasks: Promise .then/.catch/.finally, await continuations, queueMicrotask, MutationObserver. Macrotasks: setTimeout/setInterval, message events, I/O. This is why an infinite chain of promises can starve rendering (microtasks never yield), while setTimeout loops let frames paint between iterations.

Use this technique when

Explaining why a Promise .then beats a setTimeout(0), why await resumes 'soon' but not synchronously, and starvation bugs where microtasks block rendering.

References

js