setInterval is used to run a function repeatedly at a set interval.
setInterval(() => console.log("Tick"), 1000);The Flaw: setInterval does not care if our function takes time to run. It schedules the next execution based on when the last one was scheduled, not when it finished.
The Fix: Recursive setTimeout.
This ensures the next timer only starts after the current one finishes.
function tick() {
console.log("Tick");
// Only schedule the next one when this one is done
setTimeout(tick, 1000);
}
setTimeout(tick, 1000);setTimeout(fn, 0)Many developers use setTimeout(fn, 0) to make code "async."
Does 0 mean Immediate? No. It means The Minimum Possible Delay.
Note: setImmediate is not a standard Web API (browsers don't support it). It is specific to the Node.js Event Loop.
Purpose: To execute a script immediately after the current Poll Phase (I/O) completes.
While setTimeout technically belongs to the Timers phase, setImmediate belongs to the Check phase of the Node.js Event Loop.
This is the critical architectural distinction in Node.js.
If we run them in the main script, the order is Non-Deterministic. It depends on system performance.
// index.js
setTimeout(() => console.log("Timeout"), 0);
setImmediate(() => console.log("Immediate"));
// Output: Could be "Timeout" -> "Immediate" OR "Immediate" -> "Timeout"If we are inside an I/O callback (like reading a file), setImmediate is guaranteed to run first.
const fs = require("fs");
fs.readFile(__filename, () => {
// We are now in the I/O Phase
setTimeout(() => console.log("Timeout"), 0);
setImmediate(() => console.log("Immediate"));
});Why?
setImmediate lives).setTimeout lives).Result:
setImmediate runs in the current tick.
setTimeout must wait for the next tick.
Output (Always):
Immediate
Timeout| Timer | Environment | Phase/Queue | Execution Time |
|---|---|---|---|
setTimeout(fn, 0) | Browser & Node | Macrotask (Timers) | Next Loop (min 1-4ms delay). |
setImmediate | Node.js only | Check Phase | Immediately after I/O. |
setInterval | Browser & Node | Macrotask (Timers) | Repeats (Subject to drift). |
Answer:
The UI rendering happens in between Macrotasks.
By using setTimeout, we yield control back to the Event Loop. The browser says, Stack is empty? Okay, let me repaint the screen first, then I'll pick up your timeout callback.
This prevents the Frozen Screen issue during heavy calculations.