SHIN
Node.js 실전 팁 20선
20편Node.js는 싱글 스레드이지만 비동기 I/O 덕분에 높은 처리량을 달성합니다. 그 핵심이 Event Loop입니다.
| 단계 | 역할 |
|---|---|
| timers | setTimeout, setInterval 콜백 실행 |
| pending callbacks | 이전 반복에서 연기된 I/O 콜백 |
| idle/prepare | 내부용 |
| poll | 새 I/O 이벤트 대기 및 실행 |
| check | setImmediate 콜백 |
| close callbacks | socket.destroy 등 close 이벤트 |
console.log('1: 동기');
setTimeout(() => console.log('2: setTimeout 0'), 0);
setImmediate(() => console.log('3: setImmediate'));
Promise.resolve().then(() => console.log('4: microtask'));
process.nextTick(() => console.log('5: nextTick'));
console.log('6: 동기');
// 출력 순서:
// 1: 동기
// 6: 동기
// 5: nextTick ← nextTick 큐 (microtask보다 우선)
// 4: microtask ← Promise 마이크로태스크 큐
// 2: setTimeout 0 ← timers 단계
// 3: setImmediate ← check 단계// nextTick > Promise.then > setImmediate > setTimeout
process.nextTick(() => console.log('nextTick 1'));
process.nextTick(() => console.log('nextTick 2'));
Promise.resolve()
.then(() => console.log('promise 1'))
.then(() => console.log('promise 2'));
setImmediate(() => console.log('immediate'));const fs = require('fs');
fs.readFile(__filename, () => {
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
// I/O 콜백 안에서는 setImmediate가 항상 setTimeout보다 먼저 실행됩니다.
});// ❌ 절대 금지 - Event Loop 블로킹
function heavySync() {
let sum = 0;
for (let i = 0; i < 1e9; i++) sum += i;
return sum;
}
// ✅ Worker Thread로 분리
const { Worker, isMainThread, parentPort } = require('worker_threads');
if (isMainThread) {
const worker = new Worker(__filename);
worker.on('message', (result) => console.log('결과:', result));
} else {
let sum = 0;
for (let i = 0; i < 1e9; i++) sum += i;
parentPort.postMessage(sum);
}