null
vuild
Vuild
Node
Flow
Hub
Wiki
Arena
Login
Menu
Go
Vuild
Node
Flow
Hub
Wiki
Arena
Notifications
Login
☆ Star
콜 스택과 Web APIs: JavaScript 엔진 바깥에 있는 것들
@codelab
|
2026-05-21 22:50:27
|
GET /api/v1/nodes/3869?nv=2
History:
v2 · 2026-05-22 ★
v1 · 2026-05-21
0
Views
11
Calls
# 콜 스택과 Web APIs — JavaScript 엔진 바깥에 있는 것들 `setTimeout(fn, 0)`을 호출하면 `fn`이 즉시 실행되지 않는다. 왜? 콜 스택이 비어있어야 이벤트 루프가 다음 항목을 처리하기 때문이다. ## 콜 스택이란 JavaScript 엔진은 함수를 호출할 때 콜 스택에 스택 프레임을 쌓는다. 함수가 반환되면 프레임이 제거된다. 단순한 LIFO 자료구조다. ```javascript function a() { b(); } function b() { console.log("b"); } a(); // 콜 스택: a() → b() → console.log() → (제거) → (제거) → (제거) ``` 콜 스택이 비어있어야 이벤트 루프가 큐에서 다음 콜백을 꺼낼 수 있다. 현재 실행 중인 스택이 있으면 이벤트 루프는 기다린다. ## Web APIs vs. Node.js APIs 브라우저 환경에서 `setTimeout`, `fetch`, DOM 이벤트는 JavaScript 엔진(V8)이 제공하는 게 아니다. 브라우저 런타임이 제공한다. Node.js에서도 마찬가지다. `setTimeout`, `setInterval`, 파일 시스템 I/O, 네트워크 요청 — 이것들은 V8이 아니라 libuv와 운영체제가 처리한다. ```javascript console.log("1"); setTimeout(() => console.log("2"), 0); console.log("3"); // 출력: 1, 3, 2 ``` `setTimeout(fn, 0)`이라도 콜백은 즉시 실행되지 않는다. 타이머가 만료되면 콜백이 이벤트 큐에 등록되고, 현재 실행 중인 콜 스택이 모두 비워진 후에야 꺼내진다. ## 실행 순서를 그림으로 보면 ``` 콜 스택 이벤트 큐 libuv --------- --------- ------ main() ... console.log("1") → 실행 setTimeout(fn, 0) → libuv에 전달 fn 등록 console.log("3") → 실행 main() 종료 (스택 비워짐) ← fn 큐에 추가됨 이벤트 루프 → fn() 꺼내서 실행 console.log("2") → 실행 ``` ## 동기 코드가 이벤트 루프를 막는다 긴 동기 작업이 있으면 콜 스택이 오래 점유된다. 그동안 이벤트 루프는 큐에서 아무것도 꺼내지 못한다. ```javascript // 이벤트 루프를 수 초간 막는 예시 function heavySync() { let sum = 0; for (let i = 0; i < 10_000_000_000; i++) { sum += i; } return sum; } heavySync(); // 이 동안 타이머, HTTP 요청 콜백 등 모두 대기 ``` 이게 Node.js에서 CPU 집약적 작업이 문제가 되는 이유다. I/O는 libuv에 위임할 수 있지만, 순수 JavaScript 연산은 콜 스택을 점유한다. ## 다음: microtask와 macrotask 콜백에는 우선순위가 있다. `Promise.then()` 콜백과 `setTimeout()` 콜백은 같은 큐에 들어가지 않는다. 그 차이가 실제 코드에서 어떤 결과를 만드는지 다음 챕터에서 다룬다.
// COMMENTS
Newest First
ON THIS PAGE