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, 네트워크, 타이머 같은 느린 작업을 직접 처리하지 않는다.
대신:
- 백그라운드에 처리를 요청
- 작업이 끝나면
- 실행할 콜백을 태스크 큐에 등록
중요한 점:
❌ 자바스크립트 코드가 백그라운드로 이동하지 않는다
⭕ “처리 요청”만 보낸다
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은 즉시 실행 | ❌ “현재 실행 종료 후” |
| 비동기 = 병렬 실행 | ❌ 실행은 여전히 싱글 스레드 |
'WEB,WAS > Nodejs' 카테고리의 다른 글
| 서버 실행 모델(spring,nodejs) 멀티스레딩 (0) | 2026.02.02 |
|---|---|
| Windows 환경에서 PM2를 서비스로 등록해 특정 계정으로 자동 재기동하기 (0) | 2025.08.19 |
댓글