Event loop tour — from Call Stack to the two queues and back
flowchart TD
S["<b>i · Call Stack</b><br/>executes code line by line"]
--> W["<b>ii · Web APIs</b><br/>timers, fetch, DOM events<br/>run in the browser"]
W --> MQ["<b>iii · Microtask Queue</b><br/>.then / .catch / .finally<br/>queueMicrotask · MutationObserver"]
W --> CQ["<b>iv · Callback Queue</b><br/>setTimeout · setInterval<br/>event handlers · I/O"]
MQ --> EL["<b>v · Event Loop</b><br/>stack empty?"]
CQ --> EL
EL -- "drain first" --> MQ
EL -- "then one task" --> CQ
EL -- "push onto stack" --> S
classDef stack fill:#f5efe1,stroke:#6a8a4f,stroke-width:2px,color:#1a1915;
classDef api fill:#fdecd3,stroke:#c2410c,stroke-width:2px,color:#1a1915;
classDef micro fill:#e7efd9,stroke:#587640,stroke-width:2px,color:#1a1915;
classDef macro fill:#f5efe1,stroke:#6a8a4f,stroke-width:2px,color:#1a1915;
classDef loop fill:#fdecd3,stroke:#c2410c,stroke-width:2px,color:#1a1915;
class S stack
class W api
class MQ micro
class CQ macro
class EL loop-
Call Stack
JS executes code line by line here. Only one thing runs at a time — this is what "single-threaded" means.
-
Web APIs
When JS hits `setTimeout`, `fetch`, or adds an event listener, the work is handed off to the browser. The stack is free to continue.
-
Microtask Queue
Promise callbacks (`.then`/`.catch`/`.finally`), `queueMicrotask`, MutationObserver — higher priority than the callback queue.
-
Callback Queue
Also called the macrotask queue: setTimeout/setInterval callbacks, event handlers, I/O callbacks — lower priority.
-
Event Loop
The gatekeeper. When the Call Stack is empty, it fully drains the Microtask Queue, then takes one item from the Callback Queue and pushes it onto the stack. Repeat forever.
Comments
Comments are disabled in this environment. Set
PUBLIC_GISCUS_REPO,PUBLIC_GISCUS_REPO_ID, andPUBLIC_GISCUS_CATEGORY_IDto enable.