nextTick & setImmediate
Two ways to defer code, running at different points in the loop.
Syntax
process.nextTick(fn);
setImmediate(fn);Node offers two ways to defer a function to run soon, but not right now:
process.nextTick(fn)— runs before the event loop continues, after the current operation. Highest priority.setImmediate(fn)— runs in the check phase, after the current poll phase completes.
Rule of thumb
Use setImmediate to yield back to the event loop. Reserve process.nextTick for urgent, small tasks — overusing it can starve the loop.
Example
console.log('start');
setImmediate(() => console.log('immediate'));
process.nextTick(() => console.log('nextTick'));
console.log('end');
// Order: start, end, nextTick, immediateWhen to use it
- A module emits an event after construction using `process.nextTick` so listeners attached in the calling code have time to register before the event fires.
- A recursive directory walker uses `setImmediate` to yield control back to the event loop between batches of entries, preventing I/O starvation.
- An error-boundary helper re-throws a caught error via `process.nextTick` so it surfaces in the event loop and triggers the `uncaughtException` handler.
More examples
process.nextTick defers until stack clears
Demonstrates that `process.nextTick` runs after the current synchronous code but before any I/O or timers.
console.log('1 sync');
process.nextTick(() => console.log('2 nextTick'));
console.log('3 sync');
// Output: 1 sync -> 3 sync -> 2 nextTickEmit event after listeners attach
Uses `process.nextTick` inside a constructor to defer event emission until the caller's synchronous code has run.
const { EventEmitter } = require('events');
class MyModule extends EventEmitter {
constructor() {
super();
// Defer so callers can attach listeners first
process.nextTick(() => this.emit('ready'));
}
}
const m = new MyModule();
m.on('ready', () => console.log('Module is ready!'));setImmediate yields to I/O
Uses `setImmediate` for recursion so I/O events are processed between iterations, avoiding starvation.
function recurse(n) {
if (n <= 0) return;
// setImmediate lets pending I/O run between iterations
setImmediate(() => recurse(n - 1));
}
recurse(100);
process.stdout.write('Server still responsive\n');
Discussion