자바스크립트 이벤트 루프

Yono·2023년 3월 22일
2

javascript

목록 보기
1/1

Node.js가 논블로킹 I/O작업을 수행할 수 있도록 해주는 핵심 기능인 이벤트 루프를 알아보자

이벤트 루프

이벤트 루프는 시스템 커널에서 가능한 작업이 있다면 그 작업을 커널에 이관한다. 자바스크립트가 단일 스레드 기반임에도 불구하고 Node.js 논블로킹 I/O 작업을 수행할 수 있도록 해주는 핵심 기능이다.

이벤트 루프에는 6개의 단계가 있다. 각 단계마다 처리해야하는 콜백 함수를 담기 위한 큐를 가지고 있다.

이벤트 루프의 구성요소는 아니지만 nextTickQueue 와 microTaskQueue가 존재한다.

nextTickQueue 와 microTaskQueue 에 들어 있는 작업은 이벤트 루프가 어느 단계에 있든 실행 될수 있다.

타이머 단계

이벤트루프는 타이머 단계(timer phase) 에서 시작한다. 타이머 단계의 큐에는 setTimeout이나 setInterval과 같은 함수를 통해 만들어진 타이머들을 큐에 넣고 실행단다. 타이머들은 최소 힙으로 관리된다. 시간이 지난 타이머들의 콜백이 무한정 실행되는 것은 아니고 시스템의 실행한도에 도달하면 다음 단계로 넘어간다.

대기 콜백 단계

대기 단계의 큐(pending_queue) 에 들어 있는 콜백들은 현재 돌고 있는 루프 이전의 작업에서 큐에 들어온 콜백이다. 에러 핸들러 콜백도 pending_queue로 들어오게 된다.

타이머 단계를 커쳐서 대기 콜백 단계에 들어오면 이전 작업들의 콜백이 pending_queue에서 대기중인지 검사한다. 만약 실행 대기 중 이라면 시스템 실행 한도에 도달할 때까지 꺼내서 실행한다.

유휴, 준비 단계

유휴 단계(idle phase)는 틱tick마다 실행된다. 준비 단계는 매 폴링 직전에 실행된다. 이 두 단계는 Node.js 내부 동작을 위한것이라고만 알고 있으면 된다.

폴 단계

이벤트 루프 중 가장 중요한 단계가 폴 (pall phase)이다. 폴 단계에서는 새로운 I/O 이벤트를 가져와서 관련 콜백을 수행한다. 예를 들어 소켓 연결과 같은 새로운 커넥션을 맺거나 파일 읽기와 같이 데이터 처리를 받아들이게 된다. 이단계가 가지고있는 큐는 watch_queue다. watch_queue가 비어 있지 않다면 큐가 비거나 시스템 실행한도에 다다를 때 까지 동기적으로 모든 콜백을 실행한다. 큐가 비게되면 Node.js는 곧바로 다음 단계로 이동하지 않고 check_queue , pending_quque, closing_callbacks_queue에 남은 작업이 있는지 검사 후 작업이 있다면 다음 단계로 이동한다. 큐가 모두 비어서 할 작업이 없다면 잠시 대기를 하게 된다.

체크 단계

체크 단계 check phasesms setImmediate의 콜백만을 위한 단계이다. 큐가 비거나 시스템 실행한도에 도달할 때까지 콜백을 수행한다.

종료, 콜백단계

종료 콜백 단계 close callback phase에서는 이벤트 타입의 콜백이 처리된다 종료 콜백을 마치고 나면 다음 루프에서 처리해야하는 작업이 남아 있는지 검사한다. 작업이 남아있다면 타이머 단계부터 한 번 더 루프를 돌게 되고 아니라면 루프를 종료한다.

nextTickQueue는 process.nextTick() API의 콜백들을 가지고 있으며 , microTaskQueue 는 resolve된 Promise의 콜백을 가지고 있다. 이 두 개의 큐는 기술적으로 이벤트 루프의 일부가 아니다. 즉 , libuv 라이브러리에 포함된 것이 아니라 Node.js에 포함된 기술이다. 이 두 큐에 들어있는 콜백은 단계를 넘어가는 과정에서 먼저 실행 된다. nextTickQueue가 microTaskQueue 보다 높은 우선순위로 처리 된다.

profile
Java,Spring,JavaScript

0개의 댓글