setTimeout, setInterval, setImmediate
Timers
Schedule code to run later. Node adds setImmediate plus a promise-based timers API.
What you'll learn
- Use setTimeout, setInterval, setImmediate
- Use timers/promises for await-able timers
- Unref a timer to let the process exit
Node has the browser’s setTimeout and setInterval, plus its own
setImmediate. And a much nicer promise-based API.
The Classics
setTimeout(() => console.log("once, later"), 1000);
const id = setInterval(() => console.log("forever"), 1000);
// later:
clearInterval(id); Browser-identical. Returns a Timer object (not a number, but it
works the same).
setImmediate
Run as soon as the current phase finishes, before any other timer:
setImmediate(() => console.log("next loop iteration"));
setTimeout(() => console.log("after 0ms"), 0);
// 'next loop iteration' typically prints first setImmediate(fn) is preferable to setTimeout(fn, 0) in Node —
it’s defined to run at a specific phase, not “approximately zero
ms from now.”
Promise-Based Timers
node:timers/promises lets you await instead of callback:
import { setTimeout as wait } from "node:timers/promises";
await wait(500);
console.log("half second later"); Much cleaner inside async functions.
Unrefing
A pending setTimeout keeps the process alive. To say “this timer
shouldn’t hold the process open”:
const id = setTimeout(() => doThing(), 60_000);
id.unref(); // process can exit before this fires Useful for periodic cleanup tasks that shouldn’t prevent shutdown.
A Scheduling Pattern
import { setTimeout as wait } from "node:timers/promises";
async function pollForever() {
while (true) {
await checkSomething();
await wait(5_000);
}
} setInterval can drift if a tick is slow. The await wait(...)
pattern guarantees fixed gaps between work.