8. 에러가 잡히지 않는 이유
Q. 비동기 함수는 왜 try-catch가 안 통할까?
자바스크립트의 try-catch는 동기(synchronous) 코드에서만 동작함
비동기 콜백(setTimeout, XMLHttpRequest, 이벤트 리스너 등)은 스택에서 벗어난 이후 나중에 실행되기 때문에 try-catch가 영향을 미치지 못하게 됨
example.js
try {
console.log('try block started');
setTimeout(() => {
throw new Error("Error!");
}, 0);
console.log('try block ended');
} catch (e) {
console.error("Caught:", e.message);
}
console.log('next line');→ setTimeout() 내 콜백 함수는 콜 스택에서 빠진 이후 실행되기 때문에 catch 블럭의 제어권을 벗어남
자바스크립트의 실행에 관여하는 내부 구조
-
콜 스택
현재 실행 중인 함수들이 쌓이는 스택 메모리
try-catch는 이 스택 안에서만 유효함 -
태스크 큐
setTimeout, XMLHttpRequest, 이벤트 리스너 등의 콜백이 나중에 실행되기 위해 대기하는 공간 -
이벤트 루프
스택이 비었을 때 큐에서 하나씩 꺼내서 스택에 넣고 실행하는 역할
코드의 동작 순서
- try-catch가 setTimeout(…)을 실행
- setTimeout은 콜백을 Callback Queue에 등록만 함 (0ms 후 실행 예약)
- try-catch 블록은 끝남 → 스택은 비게 됨
- Event Loop가 콜백 큐에서 콜백 꺼내서 다시 스택에 올림
- 그때서야 throw new Error(…) 실행됨
- 하지만 이 코드는 이미 try-catch 바깥에서 실행됨
- 즉, setTimeout 콜백이 실행될 땐, try-catch가 존재하지 않는 새로운 스택 위에서 실행되고 있는 것
정리하면
1. 스택 스코프 한계 - try-catch는 현재 call stack에서만 유효함
2. 콜백은 나중에 실행됨 - setTimeout, XHR, 이벤트 등은 다음 스택에서 실행됨
→ 따라서 콜백 내부 예외는 catch의 보호 범위를 벗어남
Last updated on