Working with Timers
1. Using setTimeout for Delays
| Form | Notes |
|---|---|
setTimeout(fn, ms, ...args) | Returns Timeout |
timeout.unref() | Don't keep loop alive |
timeout.ref() | Reverse |
timeout.refresh() | Restart |
2. Using setInterval for Repetition
Example
const id = setInterval(() => checkHealth(), 30_000);
process.on("SIGTERM", () => clearInterval(id));
3. Using setImmediate for Next Cycle
| Use Case | Why |
|---|---|
| Yield to I/O | Run after current poll phase |
Avoid nextTick starvation | Spreads work across ticks |
4. Using process.nextTick for Microtasks
| Order | Detail |
|---|---|
| Highest priority | Drained before microtasks/macrotasks |
| Use for | Defer logic to "after current op completes" |
5. Clearing Timeouts (clearTimeout)
6. Clearing Intervals (clearInterval)
| API | Use |
|---|---|
clearInterval(id) | Stop repeating timer |
7. Clearing Immediate (clearImmediate)
| API | Use |
|---|---|
clearImmediate(id) | Cancel scheduled setImmediate |
8. Understanding Timer Order
| Same delay | Tie break |
|---|---|
setTimeout(fn, 0) | Min 1ms; runs in timers phase |
setImmediate | Always runs in check phase |
| From within I/O cb | setImmediate runs first |
9. Using Timers/Promises
Example: Promise-based timers v15+
import { setTimeout, setInterval } from "node:timers/promises";
await setTimeout(1000); // sleep 1s
for await (const _ of setInterval(500)) // tick every 500ms
console.log("tick");
10. Handling Timer Drift
| Issue | Mitigation |
|---|---|
| Event loop blocking delays callbacks | Use absolute timestamps + adjust |
| Long intervals accumulate drift | Reschedule using Date.now() |
| OS sleep affects timers | Detect via wall-clock check |
11. Scheduling Delayed Tasks
| Tool | Use |
|---|---|
| node-cron / cron | Cron-style schedules |
| node-schedule | One-shot + recurring |
| BullMQ / Agenda | Persistent job queues |