setImmediate()
이해하기
비동기적으로, 하지만 가능한 한 빨리 일부 코드를 실행하고 싶을 때, Node.js에서 제공하는 setImmediate()
함수를 사용하는 방법이 있습니다.
setImmediate(() => {
// do something
})
setImmediate()
인수로 전달된 함수는 이벤트 루프의 다음 반복에서 실행되는 콜백입니다.
setImmediate()
는 setTimeout(() => {}, 0)
(0ms 타임아웃 전달)과 process.nextTick()
및 Promise.then()
과 어떻게 다를까요?
process.nextTick()
에 전달된 함수는 현재 작업이 끝난 후 이벤트 루프의 현재 반복에서 실행됩니다. 즉, 항상 setTimeout
및 setImmediate
보다 먼저 실행됩니다.
0ms 지연의 setTimeout()
콜백은 setImmediate()
와 매우 유사합니다. 실행 순서는 다양한 요인에 따라 달라지지만 둘 다 이벤트 루프의 다음 반복에서 실행됩니다.
process.nextTick
콜백은 process.nextTick 큐에 추가됩니다. Promise.then()
콜백은 promises 마이크로태스크 큐에 추가됩니다. setTimeout
, setImmediate
콜백은 매크로태스크 큐에 추가됩니다.
이벤트 루프는 먼저 process.nextTick 큐의 작업을 실행하고, 그다음 promises 마이크로태스크 큐를 실행하고, 그다음 setTimeout
또는 setImmediate
매크로태스크 큐를 실행합니다.
다음은 setImmediate()
, process.nextTick()
및 Promise.then()
사이의 순서를 보여주는 예입니다.
const baz = () => console.log('baz');
const foo = () => console.log('foo');
const zoo = () => console.log('zoo');
const start = () => {
console.log('start');
setImmediate(baz);
new Promise((resolve, reject) => {
resolve('bar');
}).then(resolve => {
console.log(resolve);
process.nextTick(zoo);
});
process.nextTick(foo);
};
start();
// start foo bar zoo baz
이 코드는 먼저 start()
를 호출한 다음 process.nextTick 큐에서 foo()
를 호출합니다. 그 후, promises 마이크로태스크 큐를 처리하여 bar를 출력하고 동시에 process.nextTick 큐에 zoo()
를 추가합니다. 그런 다음 방금 추가된 zoo()
를 호출합니다. 마지막으로 매크로태스크 큐의 baz()
가 호출됩니다.
앞서 언급한 원칙은 CommonJS의 경우에 적용되지만, ES 모듈(예: mjs
파일)에서는 실행 순서가 다를 수 있습니다.
// start bar foo zoo baz
이는 로드되는 ES 모듈이 비동기 작업으로 래핑되어 있기 때문에 전체 스크립트가 실제로 이미 promises 마이크로태스크 큐
에 있기 때문입니다. 따라서 프로미스가 즉시 해결되면 해당 콜백은 마이크로태스크 큐
에 추가됩니다. Node.js는 다른 큐로 이동할 때까지 큐를 지우려고 시도하므로 먼저 bar가 출력되는 것을 볼 수 있습니다.