Interview question
Why does setTimeout(fn, 0) not run immediately? setTimeout(fn, 0) तुरंत क्यों नहीं चलता?
Answer
Even with a 0ms delay, setTimeout's callback is placed in the macrotask queue and must wait for the current synchronous code AND the entire microtask queue to finish before it can run.
console.log('1: First');
setTimeout(() => {
console.log('3: setTimeout (0ms)');
}, 0);
console.log('2: Second');
// Output: 1: First, 2: Second, 3: setTimeout (0ms)
// Even at 0ms delay, the callback ALWAYS runs after all sync code
// setTimeout(fn, 0) is also queued AFTER any pending microtasks
setTimeout(() => console.log('macrotask'), 0);
Promise.resolve().then(() => console.log('microtask'));
console.log('sync');
// Output: sync, microtask, macrotask - microtask ALWAYS wins even against 0ms timeout
// Additional browser detail: minimum delay clamping
// Nested setTimeout calls (deeper than a certain level) get clamped to a minimum of 4ms
function nestedTimeouts(count) {
if (count > 5) return;
setTimeout(() => {
console.log(`Nested call ${count}`);
nestedTimeouts(count + 1);
}, 0); // browsers may enforce a minimum ~4ms after nesting depth 5
}
// Practical use of setTimeout(fn, 0): deferring work until after
// the current synchronous execution and rendering finishes
function updateUI() {
document.body.style.background = 'blue'; // change happens
setTimeout(() => {
console.log('UI change should be painted by now');
}, 0);
}
// This is why setTimeout(fn, 0) is sometimes used as a way to "yield"
// control back to the browser/event loop before continuing heavy work0ms delay के बावजूद, setTimeout का callback macrotask queue में जाता है और इसे चलने से पहले current synchronous code AND पूरी microtask queue खत्म होने का इंतज़ार करना पड़ता है।
console.log('1: First');
setTimeout(() => {
console.log('3: setTimeout (0ms)');
}, 0);
console.log('2: Second');
// Output: 1: First, 2: Second, 3: setTimeout (0ms)
// 0ms delay के बावजूद callback हमेशा सभी sync code के बाद चलता है
// setTimeout(fn, 0) pending microtasks के बाद भी queue होता है
setTimeout(() => console.log('macrotask'), 0);
Promise.resolve().then(() => console.log('microtask'));
console.log('sync');
// Output: sync, microtask, macrotask - microtask हमेशा 0ms timeout से आगे
// Browser detail: minimum delay clamping
// गहराई से nested setTimeout calls minimum ~4ms तक clamp हो सकते हैं
function nestedTimeouts(count) {
if (count > 5) return;
setTimeout(() => {
console.log(`Nested call ${count}`);
nestedTimeouts(count + 1);
}, 0);
}
// setTimeout(fn, 0) का practical उपयोग: current sync execution
// और rendering खत्म होने के बाद तक काम defer करना
function updateUI() {
document.body.style.background = 'blue';
setTimeout(() => {
console.log('UI change अब तक paint हो चुका होगा');
}, 0);
}Was this answer clear?