본문 바로가기
WEB,WAS/Nodejs

Node.js 이벤트 루프 정리(콜 스택 · 백그라운드 · 태스크 큐 · Promise · 엔진과 런타임)

by Rainbound-IT 2026. 2. 2.
반응형

 

Node.js를 공부하다 보면 반드시 헷갈리는 개념이 있다.

바로 이벤트 루프(Event Loop), 콜 스택(Call Stack), 태스크 큐(Task Queue), 그리고 백그라운드다.

책에서는 종종 “동작”부터 설명하고,

독자는 “구조를 모르는데 이게 왜 이렇게 되지?”라는 의문을 갖게 된다.

이 글에서는 다음 질문에 답한다.

  • 이벤트 루프는 정확히 뭘 하는가?
  • 콜 스택과 태스크 큐의 역할은 무엇인가?
  • 백그라운드는 어디에 속하는가?
  • setTimeout(fn, 0)은 왜 항상 나중에 실행되는가?
  • Promise / async·await 는 왜 더 먼저 실행되는가?
  • 엔진과 런타임은 무엇이 다른가?

1. 자바스크립트는 어디에서 실행되는가

결론부터 말하면, 자바스크립트 코드는 오직 콜 스택에서만 실행된다.

JS 코드 실행 장소 = Call Stack
  • 동기 코드
  • 콜백 함수
  • Promise.then
  • async/await 이후 코드

전부 콜 스택에서 실행된다.

이 점이 모든 이해의 출발점이다.


2. 콜 스택(Call Stack)이란 무엇인가

역할

지금 실행 중인 함수들의 실행 흐름을 관리하는 공간

functiona() {
b();
}
functionb() {
c();
}
functionc() {}

a();

실행 중 콜 스택 상태:

a
└─b
   └─ c

특징

  • 싱글 스레드
  • 한 번에 하나만 실행
  • 비어 있어야 다음 작업 가능

👉 콜 스택이 막히면 이벤트 루프도 멈춘다


3. “비동기”가 발생하면 무슨 일이 일어나는가

자바스크립트는 파일 I/O, 네트워크, 타이머 같은 느린 작업을 직접 처리하지 않는다.

대신:

  1. 백그라운드에 처리를 요청
  2. 작업이 끝나면
  3. 실행할 콜백을 태스크 큐에 등록

중요한 점:

❌ 자바스크립트 코드가 백그라운드로 이동하지 않는다

⭕ “처리 요청”만 보낸다


4. 백그라운드(Background)는 무엇인가

역할

JS 엔진이 할 수 없는 작업을 처리하는 영역

  • 타이머
  • 파일 I/O
  • 네트워크
  • DNS

Node.js에서는 이 역할을 libuv + OS가 담당한다.

👉 백그라운드는 실행 주체이지, 메모리가 아니다.


5. 태스크 큐(Task Queue)는 무엇인가

역할

“나중에 실행될 콜백 함수들의 대기열”

여기에 들어오는 것들:

  • setTimeout
  • setInterval
  • I/O 콜백
  • 이벤트 핸들러

중요한 규칙:

  • 여러 개가 쌓일 수 있다
  • 하지만 한 번에 하나만 실행된다

6. 이벤트 루프(Event Loop)의 정확한 역할

이벤트 루프는 실행하지 않는다.

오직 스케줄링만 한다.

정확한 규칙

콜 스택이 비어 있는지 확인비어 있으면큐에서 콜백 하나를 꺼내콜 스택에 올린다

실행은 항상 JS 엔진이 한다.


7. setTimeout(fn, 0)은 왜 바로 실행되지 않는가

console.log("A");

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

console.log("C");
console.log("D");
console.log("E");

출력:

A
C
D
E
B

이유

  • setTimeout(fn, 0)은 즉시 실행이 아니다
  • 의미는:
  • “현재 실행이 끝난 뒤, 가능한 한 빨리 실행”

동기 코드(C, D, E)가 모두 끝나야

이벤트 루프가 태스크 큐에서 B를 가져온다.


8. Promise / async·await 는 왜 더 먼저 실행되는가

이벤트 루프에는 큐가 두 종류 있다.

1️⃣ 마이크로태스크 큐 (Microtask Queue)

  • Promise.then
  • catch
  • finally
  • await 이후 코드

2️⃣ 태스크 큐 (Task Queue)

  • setTimeout
  • I/O 콜백

실행 우선순위 규칙

콜 스택이 비면

마이크로태스크 큐를 전부 처리한 뒤

태스크 큐에서 하나를 처리한다

그래서:

setTimeout(() =>console.log("task"),0);
Promise.resolve().then(() =>console.log("microtask"));

출력:

microtask
task

9. 엔진(Engine)과 런타임(Runtime)의 차이

엔진 (예: V8 JavaScript Engine)

자바스크립트 코드를 실행하는 핵심 실행기

  • 콜 스택 관리
  • 힙(Heap) 메모리 관리
  • 가비지 컬렉션(GC)
  • JS 문법/규칙 수행

👉 “실행 담당”


런타임 (예: Node.js)

엔진이 동작할 수 있게 해주는 전체 환경

  • libuv
  • 백그라운드 처리
  • 이벤트 루프
  • 태스크 큐 / 마이크로태스크 큐
  • 파일/네트워크 API

👉 “운영 환경”


10. 전체 구조를 한 번에 정리하면

[ JS Engine (V8) ]
 ├─ Call Stack   ← 실행 흐름
 ├─ Heap         ← 객체 메모리
 └─ GC           ← 메모리 정리

[ Node.js Runtime ]
 ├─Background (libuv / OS)
 ├─ Task Queue
 ├─ Microtask Queue
 └─ Event Loop   ← 스케줄러

11. 자주 생기는 오해 정리

 

오해  실제
이벤트 루프가 코드를 실행한다 ❌ 실행은 JS 엔진
태스크 큐는 메모리다 ❌ 스케줄링 자료구조
setTimeout 0은 즉시 실행 ❌ “현재 실행 종료 후”
비동기 = 병렬 실행 ❌ 실행은 여전히 싱글 스레드
반응형

댓글