setTimeout(fn, 5000) does not guarantee 5 seconds. It guarantees at least 5 seconds. If the stack is busy, it could be much longer.
Save
Complete lesson & earn 250 PX
EXERCISE
1setTimeout(fn, 5000) does NOT guarantee that fn runs after exactly 5 seconds. It guarantees that fn will run after AT LEAST 5 seconds. It could be longer.
Save
This is a subtle but critical distinction. The timer tells the browser "wait at least this long". But the callback still has to wait for the call stack to be empty.
setTimeout 0 does not mean "run immediately":
console.log("Start");
setTimeout(function() {
console.log("Timer");
}, 0);
console.log("End");
// Output: Start, End, Timer
// Even with 0ms delay, the callback STILL goes through:
// 1. Web API (timer expires immediately)
// 2. Callback queue (waits in line)
// 3. Event loop (waits for stack to be empty)
// 4. Only THEN runs on the call stack
A busy call stack delays the callback:
console.log("Start");
setTimeout(function() {
console.log("Timer fired");
}, 5000);
// Simulate heavy work that takes 10 seconds
var start = Date.now();
while (Date.now() - start < 10000) {
// blocking the main thread for 10 seconds
}
console.log("Heavy work done");
// Output:
// Start
// Heavy work done (after 10 seconds)
// Timer fired (immediately after, NOT at 5 seconds!)
// The timer expired at 5 seconds
// But the callback was stuck in the queue
// because the call stack was busy with the while loop
// Total wait: ~10 seconds instead of 5
> Key Insight: setTimeout does not say "run after 5 seconds". It says "after 5 seconds, put me in the callback queue, and I will run whenever the call stack is free." If the stack is busy for 10 seconds, a 5-second timer actually takes 10+ seconds. The delay is a minimum, never a guarantee.
The delay is a minimum, not a guarantee. setTimeout(fn, 0) still goes through the queue. A busy call stack delays all queued callbacks. The browser is multi-threaded; is not.