setTimeout(fn, 0)
Short answer
setTimeout(fn, 0) does not execute the function instantly.
It simply places the fn callback into the macrotask queue so it runs after the current code and all microtasks finish.
Example
javascript
console.log('A');
setTimeout(() => console.log('B'), 0);
console.log('C');Output:
javascript
A
C
BWhy not A -> B -> C?
What happens step by step
console.log('A')- runs immediately (on the Call Stack).setTimeout(() => console.log('B'), 0)- hands the task to the Web API (a timer with a0ms delay).- The timer "fires" instantly, and the callback is added to the macrotask queue.
- JS continues running the current stack (
console.log('C')). - When the call stack is empty, the Event Loop takes the
() => console.log('B')task from the queue and runs it.
Why even 0 does not run immediately
Because everything in JavaScript works through the Event Loop, and it never interrupts the current call stack.
Even with a
0delay, the callback still has to wait until the stack is free.
So setTimeout(fn, 0) is a way to defer a function's execution to the next iteration of the Event Loop.
Example with a promise (a microtask)
javascript
setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('end');Order:
javascript
end
promise
timeoutExplanation:
Promise.then()creates a microtask,setTimeout()creates a macrotask,- and microtasks always run before macrotasks.
Practical uses
- Defer execution so as not to block the main code:
javascript
setTimeout(() => {
console.log('Runs after the main code');
}, 0);- Break up a synchronous loop so the UI has time to update:
javascript
for (let i = 0; i < 1e9; i++) {} // heavy operation
console.log('UI froze...');
setTimeout(() => {
console.log('Now running after the pause');
}, 0);- Reset the stack (for example, in recursive computations):
javascript
function nextStep() {
setTimeout(nextStep, 0); // each repetition is a new Event Loop iteration
}
nextStep();Summary
| Parameter | Value |
|---|---|
| What it does | Places a callback into the macrotask queue |
| When it runs | After the current stack and all microtasks |
| The "0" delay | Not instant - happens on the next Event Loop cycle |
| Queue | Macrotasks |
| Returns | A timer ID (can be canceled via clearTimeout) |
Visually
javascript
[Call Stack] → runs the current code
[Microtask Queue] → promises and queueMicrotask
[Task Queue] → setTimeout(fn, 0)setTimeout(fn, 0) always waits until:
- the call stack is cleared,
- the microtasks have run,
- and only then does
fnrun.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.