반응형
node.js 앱은 어느 시점에 종료되는 걸까요?
이벤트 루프의 각 반복이 끝날 때마다 Node.js는 앱을 종료해야 하는지 판단합니다.
이를 위해 보류 중(pending)인 시간 제한(timeout)의 레퍼런스 카운트(reference count)를 세고 있습니다.
- setImmediate(), setInterval() 또는 setTimeout()을 통해 시간이 지정된 작업을 예약하면 레퍼런스 카운트가 증가합니다.
- 시간 지정 작업을 실행하면 참조 횟수가 줄어듭니다.
이벤트 루프 반복이 끝날 때 참조 횟수가 0이면 Node.js가 종료됩니다.
다음 예에서 확인할 수 있습니다.
function timeout(ms) {
return new Promise(
(resolve, _reject) => {
setTimeout(resolve, ms); // (A)
}
);
}
await timeout(3_000);
Node.js는 timeout()이 반환한 Promise가 fullfilled될 때까지 기다립니다.
라인 A에서 스케쥴한 작업이 이벤트 루프를 활성 상태로 유지하기 때문입니다.
반대로 Promise 생성은 레퍼런스 카운트를 증가시키지 않습니다.
function foreverPending() {
return new Promise(
(_resolve, _reject) => {}
);
}
await foreverPending(); // (A)
- 이 경우 실행은 라인 A에서 await 하는 동안 일시적으로 이 (메인) 태스크를 떠납니다.
- 이벤트 루프가 끝나면 참조 횟수가 0이 되고 Node.js가 종료됩니다.
- 그러나 종료에 성공하지 못합니다. 즉, 종료 코드는 0이 아니라 13입니다(“Unfinished Top-Level Await”).
타임아웃의 레퍼런스 카운트가 node.js를 종료하지 못하게 막는 것은 의도되지 않은 동작일 수 있습니다.
이를 위해 class Timeout은 .unref와 ref 메서드를 제공합니다.
사용 사례 탐구 : Tim Perry mentions a use case for .unref()
참고
https://exploringjs.com/nodejs-shell-scripting/ch_nodejs-overview.html
반응형
'FrontEnd' 카테고리의 다른 글
Vue3과 서버사이드 렌더링(SSR) (0) | 2023.01.19 |
---|---|
ECMAScript(ESM)의 module resolution(모듈 해석)에 대해 알아보자 (0) | 2023.01.16 |
Vue3로 debounce, throttle 구현하기 (0) | 2023.01.13 |
npm link를 이용하여 서드파티 npm 패키지 커스터마이징 (0) | 2023.01.12 |
[번역] Commander.js와 Typescript를 이용하여 CLI 만들기 (0) | 2023.01.12 |