백엔드/Node.js

[NodeJS]이벤트 루프 동작 이해하기

SparkIT 2025. 3. 19. 16:17

node js 동작 구조

 

용어 정리

  • 콜 스택(Call stack)
    수행해야 하는 함수들 대기 장소(To Do List 같은 역할). 실제로 노드가 함수들을 실행하기 위해 확인하는 곳이라고 생각하면 됩니다. 노드 엔진은 콜 스택에 함수들이 대기하고 있으면 가장 마지막부터(스택의 성격: 선입후출) 차례로(동기적으로) 해당 함수들을 실행합니다. 이벤트 루프는 콜 스택에 있던 함수들이 모두 처리되어 비어있는지 항상 체크합니다. 만약 이벤트 루프가 콜 스택이 비어있음을 확인하면, 마이크로태스크 큐 / 테스크 큐 / 애니메이션 프레임 순서로 체크하며 해당 큐에서 대기 중이던 콜백 함수를 콜 스택에 채워 넣습니다.
  • 이벤트 루프(Event loop)
    이벤트 루프는 비동기적인 작업 처리를 위해 여러 작업들의 처리 순서를 정리해주는 교통경찰 역할을 많이 합니다. 예를 들어 백그라운드 스레드에서 비동기 작업이 완료되었을 때 해당 작업의 콜백 함수를 태스크 큐에 추가하는 작업도 이벤트 루프가 하고, 콜 스택에 비었을 때 이벤트 큐에서 대기 중인 콜백 함수를 콜 스택으로 이동시켜 실행하는 작업도 이벤트 루프가 합니다. 이벤트 루프는 메인 스레드라 혹은 싱글 스레드라고도 불립니다. 보통 노드를 싱글 스레드로 동작한다고 많이 표현하는데, 여기서 말하는 싱글 스레드가 이벤트 루프를 의미하기 때문입니다.
  • 마이크로테스크 큐(Microtask Queue)
    우선 순위가 1등인 콜백 큐입니다. 즉, 콜 스택이 비어있을 때 이벤트 루프가 가장 먼저 마이크로테스크 큐의 콜백 함수를 콜 스택으로 이동시켜 줍니다. 대표적으로 마이크로태스크 큐에 담기는 작업은 Promise가 있습니다.
  • 테스크 큐(Task Queue)
    우선 순위가 2등인 콜백 큐입니다. 대표적으로 태스크 큐에 담기는 작업은 setTimeout, setInterval, I/O 작업이 있습니다.
  • 애니메이션 프레임(Animation frames)
    우선 순위가 3등인 콜백 큐입니다.

 

동작 원리

간단한 예시를 통해 노드js 동작 원리를 설명하겠습니다.

console.log('Start');

setTimeout(() => {
  console.log('setTimeout');
}, 0);

Promise.resolve()
  .then(() => {
    console.log('Promise 1');
  })
  .then(() => {
    console.log('Promise 2');
  });

console.log('End');

 

  1. 콜 스택이 동기 코드를 먼저 실행
    Start → End 순으로 출력됨.
  2. setTimeout태스크 큐에 넣어짐
  3. Promise는 마이크로태스크 큐에 넣어짐
    이벤트 루프는
    콜 스택이 비었을 때 마이크로태스크 큐의 작업을 먼저 처리합니다. 즉, Promise의 콜백인 Promise 1, Promise 2가 순서대로 출력됩니다.
  4. 마이크로태스크 큐가 비면, 이벤트 루프는 태스크 큐에 대기 중인 setTimeout의 콜백을 처리
    setTimeout의 콜백인 setTimeout이 출력됩니다.