Skip to main content

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 B

Why not A -> B -> C?

What happens step by step

  1. console.log('A') - runs immediately (on the Call Stack).
  2. setTimeout(() => console.log('B'), 0) - hands the task to the Web API (a timer with a 0 ms delay).
  3. The timer "fires" instantly, and the callback is added to the macrotask queue.
  4. JS continues running the current stack (console.log('C')).
  5. 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 0 delay, 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 timeout

Explanation:

  • Promise.then() creates a microtask,
  • setTimeout() creates a macrotask,
  • and microtasks always run before macrotasks.

Practical uses

  1. Defer execution so as not to block the main code:
javascript
setTimeout(() => { console.log('Runs after the main code'); }, 0);
  1. 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);
  1. Reset the stack (for example, in recursive computations):
javascript
function nextStep() { setTimeout(nextStep, 0); // each repetition is a new Event Loop iteration } nextStep();

Summary

ParameterValue
What it doesPlaces a callback into the macrotask queue
When it runsAfter the current stack and all microtasks
The "0" delayNot instant - happens on the next Event Loop cycle
QueueMacrotasks
ReturnsA 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:

  1. the call stack is cleared,
  2. the microtasks have run,
  3. and only then does fn run.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.