Why JavaScript Doesnât Wait: The Story Behind the Event Loop
The event loop in JavaScript is a mechanism that manages asynchronous execution by moving tasks from queues to the call stack when it becomes empty, prioritizing microtasks over macrotasks to ensure efficient and non-blocking behavior.
Thereâs a moment when working with JavaScript where things stop behaving the way you expect.
You write code in orderâŚ
but the output comes out differently.
A setTimeout with 0 delay runs later.
A Promise runs before something you thought came first.
And it starts to feel like JavaScript is doing things out of order.
But itâs not.
Itâs following a system.
That system is the event loop.
JavaScript Can Only Do One Thing at a Time
At its core, JavaScript is single-threaded.
It can only execute one piece of code at a time.
That means:
- no true parallel execution
- no multitasking inside the engine
So naturally, a question appears.
How does JavaScript handle things like:
- API calls
- timers
- user interactions
All happening âat the same timeâ?
Code Runs on the Call Stack
When JavaScript executes code, it uses something called the call stack.
Think of it as the place where functions are executed.
console.log("A")
console.log("B")This runs in order:
A
BSimple. Predictable.
But this only applies to synchronous code.
When Time Enters the Picture
Now consider this:
console.log("A")
setTimeout(() => {
console.log("B")
}, 0)
console.log("C")If JavaScript is single-threaded, what happens here?
Does it pause and wait?
No.
Instead, it delegates.
The Role of the Environment
Functions like setTimeout are not handled by JavaScript itself.
They are handled by the environment:
- browser
- Node.js
So when JavaScript sees setTimeout, it says:
âHandle this elsewhere, and let me know when itâs done.â
The timer runs outside the call stack.
Meanwhile, JavaScript continues executing:
A
CThe Callback Queue
When the timer finishes, the callback doesnât run immediately.
It is placed into a queue.
Waiting.
But waiting for what?
Enter the Event Loop
The event loop is a simple but powerful idea.
It constantly checks:
Is the call stack empty?
If yes:
Take the next task from the queue and push it to the stack.
So after A and C finish, the stack becomes empty.
Then the event loop takes the callback:
console.log("B")And executes it.
Final output:
A
C
BNot All Tasks Are Equal
Thereâs another layer that often causes confusion.
Not all asynchronous tasks go into the same queue.
There are two important types:
- microtasks
- macrotasks
Microtasks: Higher Priority
These include:
Promise.thenqueueMicrotask
They run as soon as the current execution finishes.
Before anything else.
Macrotasks: Lower Priority
These include:
setTimeoutsetInterval- DOM events
They run after microtasks are done.
When Order Feels Wrong
Consider this:
console.log("A")
setTimeout(() => console.log("B"), 0)
Promise.resolve().then(() => console.log("C"))
console.log("D")You might expect B before C.
But the result is:
A
D
C
BBecause microtasks always run before macrotasks.
The Real Flow
Every cycle of JavaScript looks like this:
- Run all synchronous code
- When stack is empty â run all microtasks
- Then run one macrotask
- Repeat
This loop never stops.
Thatâs why itâs called the event loop.
Why This Is Hard to Remember
Most of the time, you donât need to think about this.
Frameworks handle complexity.
Async behavior âjust worksâ.
So your brain doesnât keep this knowledge active.
It feels theoretical.
Until something breaks.
When It Becomes Real
The event loop becomes important when:
- execution order feels wrong
- state updates donât happen immediately
- async behavior creates unexpected results
Thatâs when this mental model becomes a tool.
Not just knowledge.
A Better Way to Approach It
Instead of trying to memorize the event loopâŚ
tie it to situations.
When something behaves unexpectedly, ask:
- is this async?
- is this a promise or a timeout?
- which queue is this using?
Thatâs when the concept sticks.
Because it becomes useful.
A Final Thought
JavaScript doesnât run things out of order.
It runs them according to a system you donât always see.
The event loop is that system.
It decides when something is ready to run.
And once you start noticing itâŚ
what once felt confusing starts to feel predictable.