이벤트 루프와 setImmediate 및 setTimeout의 실행 순서

2024. 11. 15. 23:27정보처리,전산/NODEJS

반응형
const fs = require('fs');

// fs.readFile은 비동기 I/O 작업이다. 파일을 읽은 후 콜백을 실행한다.
fs.readFile(__filename, () => {
    // 이 안에서 setTimeout과 setImmediate를 호출한다.
    setTimeout(() => {
        console.log('timeout');
    }, 0);

    setImmediate(() => {
        console.log('immediate');
    });
});
  1. fs.readFile 호출:
    • fs.readFile은 비동기적으로 파일을 읽는다. 이때 파일을 읽는 작업은 Node.js의 libuv 라이브러리에 의해 처리된다.
    • 파일을 읽는 동안 Node.js는 다른 작업을 처리할 수 있으며, 파일을 읽는 작업이 완료되면 이벤트 루프의 Pending I/O Callbacks Phase로 돌아간다.
  2. setTimeout과 setImmediate:
    • 파일을 다 읽은 후 setTimeout과 setImmediate가 실행된다.
    • setTimeout은 타이머 큐에 콜백을 추가하고, setImmediate는 Check phase에 콜백을 추가한다.
  3. 이벤트 루프 흐름:
    • 이벤트 루프는 Phases를 순차적으로 진행한다:
      1. Timers Phase: setTimeout, setInterval의 콜백을 실행한다.
      2. I/O callbacks Phase: fs.readFile 같은 비동기 I/O 작업의 콜백을 실행한다.
      3. Idle, Prepare Phase: 내부적으로 사용된다.
      4. Poll Phase: 대부분의 비동기 I/O 이벤트가 이곳에서 처리된다.
      5. Check Phase: setImmediate 콜백이 실행되는 곳이다.
      6. Close callbacks Phase: process.on('exit') 등 종료 관련 콜백이 실행된다.
  4. 왜 setImmediate가 먼저 실행되나요?
    • setImmediate는 항상 Check Phase에서 실행되며 I/O 작업이 완료된 직후에 실행된다.
    • 반면, setTimeout은 Timers Phase에서 실행되며, setTimeout의 콜백은 해당 타이머의 시간이 만료될 때 실행된다. setTimeout의 콜백은 항상 Timers Phase에 등록된다.
    • 즉, setImmediate는 I/O 작업이 완료된 후 바로 실행되는 구조이고, setTimeout은 타이머가 만료된 후 실행되므로, 타이머 큐에서 대기하고 이벤트 루프의 타이머 단계에서 실행된다.

실행 순서:

  1. fs.readFile이 시작된다. 이벤트 루프는 이 작업을 비동기적으로 처리하고, 작업이 끝날 때까지 다른 작업을 처리할 수 있다.
  2. setTimeout(0)과 setImmediate가 호출된다. setTimeout은 Timers Phase에, setImmediate는 Check Phase에 등록된다.
  3. 파일을 읽은 후 Pending I/O callback phase에서 fs.readFile의 콜백이 실행된다.
  4. 이벤트 루프는 Check Phase로 넘어가며 setImmediate의 콜백을 실행한다.
  5. 이벤트 루프는 Timers Phase로 넘어가며 setTimeout(0)의 콜백을 실행한다.
immediate
timeout

왜 setImmediate가 먼저 실행되는지:

  • setImmediate는 setTimeout보다 우선적으로 실행된다. 왜냐하면 setImmediate는 I/O 작업이 완료된 후 바로 실행되도록 설계되어 있기 때문이다. 반면 setTimeout은 타이머가 만료된 후 실행된다.
  • 이로 인해 setImmediate는 Check phase에서 처리되고, setTimeout은 Timer phase에서 처리되기 때문에 setImmediate가 먼저 실행된다.
 
 

 

 

반응형