Javascipt를 제대로 이해하기 위해 글을 쓴다.
JS 엔진
가장 대중적인 JS엔진은 구글의 V8엔진이다. 크롬과 nodeJS의 엔진이다.
JS엔진은 메모리힙과 호출스택으로 구성된다.
메모리힙
메모리힙에는 구조화되지 않는 메모리영역(C언어의 동적할당을 생각하면 될 것 같다.)이 할당된다.
변수와 객체에 대한 모든 메모리 할당이 발생한다.
호출스택
코드가 실행될 때 한줄씩 호출 스택이 쌓이게된다.
call stack에는 anonymous(node에선 main)라는 전체 코드를 가지고 있는 것이 call stack에 담기게 된다.
JS는 싱글스레드이다.
한번에 하나의 일 밖에 처리할 수 없다.
이말인 즉슨, call stack이 하나라는 것이다.
하나의 함수가 실행되는 중에 다른 일을 할 수 가 없고, 다른 일들이 block되게 된다.
call stack이 꽉차는 경우, 오류가 발생하게 된다.(Overflowing)
브라우저, 엔진마다 call stack이 다르다.
동기와 비동기
아아 나왔다 동기와 비동기..
지금까지의 무지성 async await를 벗어나기 위해 이 게시글을 작성하게 된 것도 있다.
동기는 앞서 싱글스레드와 같은 말이다.
console.log(1);
console.log(2);
console.log(3);
을 찍는다고 하면, 순서대로 1,2,3이 찍히는 것을 확인할 수 있다.
이걸 내부 구조에서 보면 call stack에 쌓였다가 실행되는 것을 볼 수 있다.
실행과정을 간단하게 그림판으로 그려보았다..
그러면 조금 더 복잡한 코드는 어떻게 작동하게될까?
아래와 같은 코드를 보자.
function test(){
console.log(2);
test2()
}
function test2(){
console.log(3);
}
console.log(1);
test()
해당 코드는 함수 호출시에 stack이 쌓이게 되어 console.log(3)이 찍힐때 까지 이와같이 작동하게 된다.
오 그럼 한문장씩 실행되고, 그전엔 다른 것들을 할 수 없다는 것을 알 수 있다.
그런데 여기서 드는 의문점이 있으니
엥 보통 html도 바꾸면서, 서버에서 정보도 받아오고, 계산이나 주문도 해주던디요??
이건 어떻게 가능한 것인가?
비동기 Web APIs
왜 이게 가능하냐면, 이벤트 핸들링이나 AJAX통신, setTimeout과 같은 경우에는 WebAPIs에서 처리해서 콜스택으로 넘겨주기 때문이다.
setTimeout의 경우에는 Timeout이, 이벤트 핸들링의 경우 DOM이, AJAX통신의 경우 AJAX가 맡아서 일을 처리한 후에 callback queue에 넣어주고, 넣어진 순서대로 Event Loop가 call stack에 담아주게 된다.
단, 이때 call stack이 비어있어야 Event Loop가 콜스택으로 옮겨준다.
이런 코드가 있다고 치자.
function timeout(){
console.log(1);
setTimeout(()=>{console.log(3);},2000);
}
timeout();
console.log(2);
얘는 어떻게 작동하게 될까?
기본적인 진행은 이전코드와 다를 바가 없다.
그러나, setTimeout은 Web APIs로 넘어가고,나머지 작업을 먼저 처리한다. setTimeout의 처리가 완료되면, 콜백함수인 console.log(3)을 callback queue로 넘겨주고, call stack이 비어있음을 확인한 Event Loop가 callback queue에서 console.log(3)을 call stack으로 넘겨준다.
또, Callback queue는Task Queue(Event Queue), Micro task Queue(Job Queue), Animation Frames로 구성된다.(실제로는 더 많다고 한다.)
Callback Queue는 우선순위 큐로, Micro task Queue, Animation Frames, Task Queue의 우선순위를 가진다.
Micro task Queue에는 then이 있다.
setTimeout의 경우에는 Task Queue로 처리된다.
참고자료
https://sculove.github.io/post/javascriptflow/