Asynchronous code and events
Understanding setImmediate()
Understand how Node.js setImmediate() runs a callback in the next event loop iteration, and how it differs from setTimeout(0) and process.nextTick().
8 minute lesson
setImmediate() schedules a callback for the check phase of a future event-loop iteration:
setImmediate(() => {
console.log('immediate')
})
It means “run after the current work yields and the loop reaches the check phase,” not “run immediately” and not “run after exactly zero milliseconds.”
Compare the three queues:
process.nextTick()runs after the current JavaScript operation, before the event loop continues to another phase.setTimeout(callback, 0)schedules a timer after a minimum delay threshold. The operating system and other work can delay it.setImmediate()runs in the check phase, after the poll phase used for I/O callbacks.
From the top level of a script, the relative order of a zero-delay timeout and an immediate should not be treated as a contract:
setTimeout(() => console.log('timeout'), 0)
setImmediate(() => console.log('immediate'))
Inside an I/O callback, the immediate is scheduled for the check phase following that poll work and normally runs before a newly scheduled zero-delay timer:
import { readFile } from 'node:fs'
readFile(import.meta.filename, () => {
setTimeout(() => console.log('timeout'), 0)
setImmediate(() => console.log('immediate'))
})
process.nextTick() is not an ordinary event-loop phase. Recursively scheduling next-tick callbacks can starve timers and I/O because Node drains that queue before continuing. Use it for narrow API-ordering needs, not for breaking up large computations.
An Immediate normally keeps the process alive. Calling .unref() allows the process to exit if that callback is the only remaining work:
setImmediate(() => console.log('may run')).unref()
Ordering details can evolve with Node and its event-loop implementation. Write code around documented phase relationships, never a race observed once on your machine.
Your action is to run the top-level and I/O examples ten times on your Node version. Record the output, then add five recursive process.nextTick() calls and explain why an unbounded version would delay other work.
Lesson completed