In a code review you see a function that logs A, schedules a setTimeout(...,0) that logs B, and resolves a Promise that logs C, all before logging D synchronously. A teammate expects the order A, B, C, D. Walk me through the actual order and why.
technical-conceptual · Senior level · software-engineering
What the interviewer is really asking
Tests genuine understanding of the event loop, the microtask-versus-macrotask distinction, and the ordering guarantees that cause real async timing bugs.
What to say
- Trace it: synchronous code (A then D) runs first to completion, then the microtask queue drains (the Promise callback, C), and only then a macrotask (the timer, B) runs, giving A, D, C, B.
- Explain the rule: after the call stack empties, the engine exhausts all microtasks (Promise callbacks, queueMicrotask) before taking the next macrotask (setTimeout, I/O), and rendering sits between them in the browser.
- Connect it to a real bug class: code that assumes a setTimeout(0) runs before a resolved Promise, or that a microtask can starve rendering by re-queuing itself indefinitely.
What to avoid
- Claiming setTimeout(...,0) runs immediately or before Promise callbacks.
- Treating all asynchronous callbacks as one undifferentiated queue with no microtask/macrotask priority.
- Saying the order is non-deterministic when it's actually well specified.
Example answers
Strong: The synchronous lines run first, so A then D. When the stack clears, microtasks drain before any macrotask, so the resolved Promise's C runs next. The setTimeout callback is a macrotask, so B runs last. Final order: A, D, C, B. The teammate's mental model misses that promises are microtasks and jump ahead of timers.
Weak: Both setTimeout and the Promise are async, so they run after the synchronous code, but between the two the order isn't really guaranteed, it depends on the engine. So roughly A, D, then B and C in whatever order they land.