How it works
- Call Stack — synchronous code executes sequentially
- When an async operation is encountered (HTTP request, setTimeout) — it is handed to Web API/libuv and runs outside the main thread
- When the operation completes — the callback enters the Callback Queue
- The Event Loop checks: if the Call Stack is empty — it moves the callback onto the stack
Macrotasks vs Microtasks
Microtasks (Promise.then, queueMicrotask) execute before the next macrotask (setTimeout, setInterval). So Promise.resolve().then(fn) runs before setTimeout(fn, 0).