Why setTimeout(fn, 0) is Never 0
You might think setTimeout(fn, 0) means "run this immediately."
Spoiler: It doesn't.
Even though we write 0, JavaScript doesn't actually execute it right now - not even close. Instead, it patiently waits for the current stack to clear, queues your function, and schedules it for the future. Yes, even 0 has to wait its turn.
🛠️ Why? Because of the Event Loop.
JavaScript runs in a single-threaded environment. Here's the basic flow:
- Code executes line-by-line in the call stack.
- setTimeout(fn, 0) puts fn into the task queue after the delay (minimum 0ms).
- The event loop checks: "Is the call stack empty? Cool. Let's pull from the queue."
- Only then does fn run.
Even 0 isn't instant because it's deferred until the current task finishes.
⚠️ Browsers Have a Minimum Delay
Most browsers enforce a minimum delay threshold (typically 4ms for nested calls). So even setTimeout(fn, 0) might not even run after 0ms — it could be 4ms+, depending on context.