Explain the event loop, the call stack, and the difference between microtasks and macrotasks.
JavaScript runs on a single thread with one call stack. Anything asynchronous is handed to the host — the browser or Node — and comes back as a queued callback.
The event loop repeats one rule: when the call stack is empty, drain the microtask queue completely, then take one task from the macrotask queue.
- Microtasks — promise callbacks (
.then, the code after anawait),queueMicrotask, andMutationObserver. The entire microtask queue is emptied before the next macrotask, and microtasks queued during that drain are also run. - Macrotasks —
setTimeout,setInterval, I/O callbacks, and UI events. Exactly one runs per turn of the loop.
So this logs 1, 4, 3, 2:
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);Note: The practical consequence is that an infinite chain of microtasks starves the macrotask queue and freezes the page, whereas setTimeout always yields.





