자바스크립트 런타임
자바스크립트 엔진
대표적인 자바스크립트 엔진은 구글 크롬의 V8이다.
V8 엔진은 크게 두 부분으로 구성된다.
- Memory Heap: 메모리 할당이 이루어지는 곳, 동적으로 생성되는 객체들을 할당 구조화되지 않은 넓은 메모리 영역을 지칭한다.
- Call Stack: 코드가 실행되면서 스택 프레임이 쌓이는 곳 종료될 때마다 해당 스택 프레임이 팝된다.
자바스크립트는 콜스택이 하나이기 때문에 한번에 하나의 일만 처리 할 수 있다.
자바스크립트 런타임
런타임 - 해당 프로그래밍 언어로 작성된 코드가 구동되는 환경
대표적인 JavaScript 런타임: 웹 브라우저, Node.js
JavaScript 엔진
- JavaScript 코드를 읽고 해석해서 실행하는 것을 담당한다.
Web API
- 웹 브라우저에 구현된 API
- 자바스크립트 엔진에서 정의되지 않았던 DOM, AJAX, setTimeout 등을 제공한다.
이벤트 루프
- 콜스택이 비었다면 태스크 큐(콜백 큐)에 있는 첫 번째 콜백을 스택에 쌓고 처리한다.
태스크 큐
콜백 큐와 태스크 큐는 같은 말인가? Callback queue는 Task queue 의 한 종류일 수 있음.
태스크 큐는 Web API 결괏값을 쌓아 두는 큐. 예를 들어 자바스크립트에서 setTimeout(cb, 3000)를 호출하게 되면, Web API는 타이머를 동작시켜 3초 후에 태스크 큐에, cb을 쌓는다.
이벤트 루프
브라우저와 Node.js에서 공통으로 제공하는 것이 이벤트 루프이다. 자바스크립트는 싱글 스레드 기반의 언어지만, 자바스크립트가 구동되는 환경(Node.js, 브라우저)은 여러 스레드가 사용된다. 여러 스레드가 사용되는 구동 환경이 자바스크립트 엔진과 연동하기 위해 사용되는 장치가 '이벤트 루프' 이다.
스레드 안에 있는 코드들을 스케줄링하고 실행시키는 역할을 담당한다.
이벤트 루프의 역할은 콜 스택과 태스크 큐를 주시하는 것이다.
태스크 큐는 구체적으로 마이크로 테스크 큐(Event Queue) 매크로 태스크큐(Job Queue)로 나뉘어진다.
API에 따라 마이크로 태스크 큐를 사용하거나 매크로 태스크 큐를 사용한다.
콜백함수를 매크로태스크 큐에 넣는 함수
- setTimeout
- setInterval
- setImmediate
- requestAnimationFrame
- I/O
- UI 렌더링
콜백함수를 마이크로태스크 큐에 넣는 함수들
주로 Promise를 사용해 만든다.
- process.nextTick
- Promise
- Object.observe
- MutationObserver
이벤트 루프의 동작방식
1. 매크로 태스크 큐에서 가장 오래된 태스크를 꺼내서 실행시킨다.
2. 마이크로 태스크 큐에 있는 모든 태스크를 실행시킨다.
3. 렌더링 작업을 실행한다.
4. 매크로 태스크 큐애 새로운 매크로 태스크가 나타날 때까지 대기한다.
5. 1번으로 돌아간다.
자바스크립트 엔진은 매크로 태스크 하나를 처리한 직후, 마이크로 태스크 큐에 있는 마이크로 태스크를 전부 처리한다.
setTimeout(cb,0)을 하는 이유는?
0초후에 실행하는 setTimeout을 하는 이유는 이벤트 루프는 콜 스택이 비어있을 때까지 기다렸다가 cb를 콜스택에 push하기 때문에
console.log('Hi');
setTimeout(function cb1() {
console.log('cb1');
}, 5000);
console.log('Bye');
위 코드를 실행하면?
1. console.log('Hi') 가 콜스택에 추가
2. 콘솔 창에 Hi가 출력
3. console.log('Hi') 가 콜스택에서 제거
4. setTimeout(function cb1() { ... })가 콜스택에 추가
6. setTimeout(function cb1() { ... })이 실행 👉브라우저가 Web API 중 하나인 타이머를 생성 타이머가 카운트다운 처리
7. setTimeout(function cb1() { ... }) 이 완료되고 콜스택에서 제거
8. console.log('Bye')가 콜스택에 추가
9. console.log('Bye') 실행
10. console.log('Bye') 제거
11. 최소한 5초가 지난 후에 타이머가 완료되고 cb1 콜백을 태스크큐에 넣음
12. 이벤트 루프는 콜 스택이 비어있는지 확인 후 태스크큐에서 cb1을 가져다가 콜스택에 넣음
13. cb1이 실행되고 console.log('cb1')이 콜스택에 추가
14. console.log('cb1') 실헹
15. console.log('cb1') 제거
16. cb1 제거
https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf
How JavaScript works: an overview of the engine, the runtime, and the call stack
As JavaScript is getting more and more popular, teams are leveraging its support on many levels in their stack - front-end, back-end…
blog.sessionstack.com
https://ko.javascript.info/microtask-queue
마이크로태스크
ko.javascript.info
https://meetup.toast.com/posts/89
자바스크립트와 이벤트 루프 : NHN Cloud Meetup
자바스크립트와 이벤트 루프
meetup.toast.com