대표적인 자바스크립트 엔진은 구글 크롬의 V8이다.
V8 엔진은 크게 두 부분으로 구성된다.
자바스크립트 엔진은 하나의 Memory Heap과 Call Stack을 가지고 있다. 따라서 구조적으로 한번에 하나의 코드만 동기적으로 실행이 가능한 싱글스레드 언어이다. 자바 스크립트가 처음 나왔을때는 멀티프로세서 컴퓨터가 거의 없었고 당시 자바스크립트로 처리할 코드의 양은 상대적으로 적었기 때문이다.
시간이 지나면서 컴퓨터가 멀티 코어 시스템으로 바뀌었고, 싱글 스레드의 한계에서 벗어날 수 있는 방법을 찾아야했다.
런타임은 해당 프로그래밍 언어로 작성된 코드가 구동되는 환경이다. 자바스크립트 코드는 다음의 두 가지 런타임 환경 중 하나에서 실행될 수 있다.
Web API는 웹 브라우저에 구현된, 자바스크립트가 실행되는 런타임 환경에 존재하는 별도의 API이다. setTimeout
setInterval
setImmediate
AJAX
DOM
등이 있다.
자바스크립트가 구동되는 환경(브라우저,Node)은 여러 스레드가 사용된다. 여러 스레드가 사용되는 구동 환경이 자바스크립트 엔진과 연동하기 위해 사용되는 장치가 '이벤트 루프' 이다.
📌Callback queue, Task queue, Macro queue 용어
어떤 블로그에서는 Task Queue의 종류에 Macro queue와 Micro queue가 들어가는거라고 되어있고 공식 문서에는The microtask queue is not a task queue.
라고 되어있었다. 찾아보니 Microtask queue와 Task queue(Macrotask queue)가 다른것이고 Macrotask와 Task queue는 같은 것이었다.
많은 곳에서 Callback queue와 Task queue를 같은 의미로 사용하고 있었는데 공식 문서에 Task queue로 나와있어서 Task queue로 적었다.
API에 따라 Task Queue를 사용하거나 Microtask Queue를 사용한다.
기본적으로 비동기 방식으로 작업을 수행 해야하는 경우 MicroTask를 사용한다. (그렇지 않으면 Task사용을 권한다.)
Task queues are sets, not queues, because step one of the event loop processing model grabs the first runnable task from the chosen queue, instead of dequeuing the first task.
Task Queue는 Task의 집합이다. 단순히 큐의 첫 번째 Task를 가져오는 것이 아니라, 실행가능한 가장 오래된 Task를 가져온다.
Task Queue - setTimeout , setInterval , setImmediate , requestAnimationFrame , I / O , UI 렌더링
비동기 작업을 처리하려면 적절한 관리가 필요하다. 이를 위해 ECMA에선 PromiseJobs
라는 내부 큐를 명시한다. V8 엔진에서는 이를 Microtask queue
라고 부른다. Microtask Queue는 Task Queue와 같은 계층에 존재한다.
queueMicrotask(func)
를 사용하면 함수 func를 마이크로태스크 큐에 넣어 처리할 수 있다.Microtask Queue - process.nextTick , Promises , queueMicrotask , MutationObserver
console.log('script start'); //A
setTimeout(function () {
console.log('setTimeout'); //B
}, 0);
Promise.resolve()
.then(function () {//C
console.log('promise1');
})
.then(function () {//d
console.log('promise2');
});
console.log('script end'); //E
console.log('script start')
가 Call Stack에 쌓였다가 'script start'를 출력하고 pop된다.setTimeout(cb,0)
함수를 Call Stack에서 Web API로 이동시키고 타이머를 실행시킨다. 타이머가 종료되면 callback함수 cb가 Task queue에 들어간다.console.log('script end')
가 Call Stack에 쌓였다가 'script end'를 출력하고 pop된다.