nextTick vs setImmediate
Overview
These two functions are famously named terribly in Node.js. setImmediate() actually queues a task to run later (in the Event Loop's Check Phase). process.nextTick() actually runs the task immediately (it halts the Event Loop entirely and executes the callback before the Loop is allowed to move to the next phase). If you want to defer heavy work to prevent blocking, use setImmediate. If you need to emit an event instantly before any other async code runs, use nextTick.
Syntax
const fs = require('fs');
console.log("1. Main Thread Start");
// Queues into the Check Phase (Runs Later)
setImmediate(() => {
console.log("4. setImmediate runs in the Check Phase");
});
// VIP Priority! Halts the event loop to run instantly!
process.nextTick(() => {
console.log("2. nextTick halts the loop and runs first!");
});
console.log("1. Main Thread End");Common Pitfalls
- Causing an Event Loop Blockade with
nextTick. BecausenextTickfires before the Event Loop can continue, if you write a recursive function usingnextTick, the Event Loop will freeze forever. It will never be able to reach the Poll phase, meaning your server will permanently stop accepting new HTTP requests.setImmediatedoes not have this flaw. - Misunderstanding the names. The creator of Node.js has publicly apologized for the naming convention.
nextTickfires immediately on the current tick.setImmediatefires on the next tick of the loop.
Interview Questions
Promise.then() and a process.nextTick(), which one executes first?process.nextTick() strictly has higher priority than Promises in the Microtask queue. Node will exhaust the entire nextTick queue completely before it even looks at resolved Promises.
Real-World Example
Using nextTick to safely emit an event asynchronously, giving the user time to attach their .on() listeners.
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {
constructor() {
super();
// If we emit right now, the user hasn't attached a listener yet!
// We use nextTick to wait exactly ONE microsecond for them to attach it.
process.nextTick(() => {
this.emit('ready');
});
}
}
const myObj = new MyEmitter();
// Because of nextTick, this listener attaches just in time!
myObj.on('ready', () => console.log('Object is ready!'));Check Your Knowledge
Test your understanding of nextTick vs setImmediate with these quick questions.