🔁
Node.js 이벤트 루프 — 브라우저와 다른 6단계 페이즈
timers → pending → idle → poll → check → close, 그리고 process.nextTick의 위치
브라우저의 이벤트 루프는 단순하다 — Task Queue + Microtask Queue. Node.js는 libuv 기반으로 6개 페이즈를 순회한다.
6개 페이즈
┌───────────────────────────┐
┌─>│ timers │ ← setTimeout, setInterval
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │ ← 이전 루프에서 지연된 I/O 콜백
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │ ← (내부 전용)
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ poll │ ← 새 I/O 이벤트 대기, I/O 콜백 실행
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ check │ ← setImmediate
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │ ← socket.on('close')
└───────────────────────────┘
setTimeout vs setImmediate
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
// 순서가 매번 다를 수 있다! (timers 페이즈 진입 시점에 따라)
// 하지만 I/O 콜백 안에서는:
fs.readFile('file', () => {
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
// 항상 immediate가 먼저 — poll → check 순서이므로
});
process.nextTick
모든 페이즈 전환 사이에 실행된다. Microtask보다도 먼저. 남용하면 이벤트 루프가 다음 페이즈로 못 넘어간다.
우선순위: process.nextTick > Promise.then > setTimeout/setImmediate
핵심 포인트
1
Node.js 이벤트 루프는 6개 페이즈를 순회 (libuv)
2
setTimeout은 timers, setImmediate은 check 페이즈에서 실행
3
I/O 콜백 안에서는 setImmediate이 항상 setTimeout보다 먼저
4
process.nextTick은 모든 페이즈 전환 사이에 실행 — 최우선 순위
사용 사례
서버 성능 튜닝 — setImmediate로 I/O 처리 후 즉시 콜백 실행
nextTick vs setImmediate 선택 — nextTick은 긴급, setImmediate은 양보