메모리 할당이 일어나는 곳
구조화되지 않은 넓은 메모리 영역
-> 객체(변수, 함수 등)들이 담긴다.
만약 아래와 같이 동기적으로 동작하는 코드만 존재한다면
Web API(=백그라운드)가 필요없고, Call Stack만으로도 동작이 가능하다
function first(){
second();
console.log("첫 번째");
}
function second(){
third();
console.log("두 번째");
}
function third(){
console.log("세 번째");
}
first();
third();
맨 처음 js파일이 호출되면 해당 파일의 코드들을 갖고 있는 anonymous(=main)이 먼저 호출되고
로직을 수행하는 동안 호출된 함수들이 Call Stack에 다 쌓이고 나서 코드가 실행된다.
pop, push를 거치면서 아래의 출력결과가 나온다
세 번째
두 번째
첫 번째
세 번째
call stack 용량이 초과되면 아래와 같은 에러가 발생합니다.
브라우저와 엔진마다 call stack의 한계점이 다르다
일반적인 경우 1만개를 가지지만 chrome의 경우 약 12만개를 가진다.
Uncaught RangeError: Maximum call stack size exceeded
console.log("시작"); // a
setTimeout(function() { // b
console.log("중간"); // c
}, 3000);
console.log("끝") // d
(1) ananymous가 들어가고 -> (2) a가 push됨 -> (3) a가 pop "시작" 출력
-> (4) b 가 push 됨 -> (5) b는 비동기함수 이므로 b가 pop되어 Web APIs에 append
-> (6) d가 push 됨 -> (7) d가 pop "끝" 출력 -> (8) ananymous pop
-> (10) 익명의 콜백함수안에 있는 c를 call stack에 push
-> (11) c가 pop "중간" 출력 -> (12) 익명의 콜백함수 pop -> (13) 인터프리터 종료
(8) b에 있는 익명의 콜백함수를 Callback Queue로 보낸다 -> (9) Event Loop가 call stack이 비어있는지 검사한 후 비어있기 때문에 Callback Queue에 있는 익명의 콜백함수를 Call Stack에 push
시작
끝
중간
b가 3000(3초)이 아니라 0이어도 결과는 동일하다
console.log("시작");
setTimeout(function(){
console.log("중간");
}, 0);
Promise.resolve()
.then(function() {
console.log("프로미스");
});
console.log("끝");
우선순위
가 더 높기 때문에 Callback Queue에 들어가서시작
끝
프로미스
중간
Task Queue = Event Queue
이고, Callback Queue 안에 Task Queue가 존재한다.
Promise는 Microtask Queue(=Job Queue)에 담기고 setTimeout()은 Task Queue에 담긴다.
우선순위는 다음과 같다
Microtask Queue > Animation Frames > Task Queue
Event Loop는 항시 동작하고 있는대, Call Stack이 비어있을 경우에
Microtask Queue를 먼저 확인해서 작업을 FIFO 처리한 후 Microtask Queue가 다 비었을 때,
Animation Frames 그리고 Task Queue 순서로 FIFO 처리한다.
console.log("시작");
setTimeout(function() {
console.log("중간");
}, 0);
Promise.resolve()
.then(function(){
console.log("프로미스");
});
requestAnimationFrame(function(){ // 실제로 이런함수는 없지만 animation frame을 호출하는 함수를 대신 나타낸 것
console.log("requestAnimationFrame");
});
console.log("끝");
위 코드의 실행결과는 아래와 같다.
시작
끝
프로미스
requestAnimationFrame
중간