JS Engine
자바스크립트 엔진은 어떻게 동기적인 코드와 비동기적인 코드를 구분해서 수행할 수 있을까?
자바스크립트 코드들은 웹 브라우저에 탑재되어 있는 자바스크립트 엔진으로 해석되고 실행된다고 배웠다.
자바스크립트 엔진은 Heap 그리고 Call Stack 으로 이루어져 있다.
Heap은 메모리를 저장하는 영역이고, Call Stack은 우리가 작성한 코드의 실행에 따라서 호출스택이라는 것을 쌓는 영역이다.
Run Time
거의 모든 자바스크립트 개발자들은 setTimeout과 같은 브라우저 내장 API를 사용한다. 그러나 이 API는 자바스크립트에서 제공하지 않는다. DOM(document), AJAX, Timeout과 같이 브라우저에서 제공하는 API를 Web APIs라고 부른다. 이 외에도 자바스크립트 엔진에 관여하는 Event Loop와 Callback Queue도 있다. 이러한 요소들이 실행과정에서 어떻게 상호작용하는지 직접 코드를 실행해보며 살펴보자.
다음 코드를 보며 Call Stack에서 코드가 처리되는 과정을 이해해보자.
자바스크립트는 최 상위 문맥인 Main Context 가장 먼저 Call Stack에 들어오게 된다. Main Context가 들어오는 순간이 프로그램 실행순간이고, 나가는 순간이 프로그램이 종료되는 순간이다.
위의 코드에서 function은 함수 생성부분이므로 생성만 하고 넘어가고, 실제 수행되는 코드는 console.log(three());이다.
순서대로 찬찬히 살펴보자.
- three()가 가장 먼저 호출되어 Main Context 바로 위에 쌓인다.
- three()를 실행시켜 결과값을 받으려 보니 two()를 실행시켜야 하고 three()위에 two()가 쌓인다.
- two()를 실행시켜 보니 one()을 실행시켜야 하고 two()위에 one이 쌓인다.
- one()을 실행시켜 1을 return하고 종료되었다.
- 종료된 함수는 바로 stack에서 제거된다.
- 이후 two()가 실행되고 return one() + 1을 반환하고 종료된다
- 이후 three()가 실행되고 return two() + 1을 반환하고 종료된다.
- console.log(three()); /// 3이 출력되고 Main Context가 종료된다.
비동기 함수의 실행 과정
다음은 비동기 작업이 자바스크립트 엔진에서 어떻게 이루어지는지 살펴보자.
- 가장 먼저 프로그램이 실행되고 Main Context가 stack에 담긴다.
- acyncAdd()의 호출이 가장 먼저 실행된다. 그리고 stack에 담긴다.
- 이후 acyncAdd() 내부의 setTimeout()이 실행되어 stack에 담긴다. 그러나 setTimeout은 비동기함수이고 cb를 포함하고 있다.
- 자바스크립트 엔진은 setTimeout과 같은 비동기함수를 webAPIs로 넘겨버린다. 여기서 3000ms를 기다리게 된다.
- Call Stack에서 setTimeout이 실행종료 될때까지 스택에 남아있지 않기 때문에 asyncAdd()는 stack에서 제거된다.
6. setTimeout의 delay가 끝나면 cb()는 stack에 들어가 실행되기 위해 Callback Queue로 옮겨진다.
7. Queue로 옮겨지게 되면, Main Context를 제외한 다른 함수가 남아있지 않는 경우 Event Loop를 통해 stack에 옮겨진다.
8. cb()를 실행하고 결과를 출력하고 난 다음에 모든 수행이 끝나고 난 뒤 Main Context가 제거된다.
'TIL' 카테고리의 다른 글
[JS] async & await (0) | 2023.06.30 |
---|---|
[JS] Promise (0) | 2023.06.26 |
[JS] 동기 & 비동기 (0) | 2023.06.20 |
[JS] 스프레드 연산자(spread operator) (0) | 2023.06.18 |
[JS] 조건문, 구조분해할당(비구조화할당) (0) | 2023.06.10 |