이벤트 루프 2탄!! Task Queue 말고 어떤 Queue???
저번에 Task Queue 하나의 Queue가 아니란 것을 이야기했다. Event Loop는 브라우저에 존재하는 여러 Queue 우선순위를 따라 어떤 task를 먼저 수행할지 결정한다. (Event Loop도 여러개가 있다)
(There are three types of event loop: Window event loop, Worker event loop, Worklet event loop 3탄!)
우리가 알고 있는 Task Queue = Callback Queue = Macro Queue 이다
PromiseJobs Queue = MicroTask Queue, PromiseJobs Queue는 ECMA에서, MicroTask Queue는 V8엔진에서 부르고 기능은 같다. 또한 Queue가 이 둘만 있는것은 아니다.
WebAP, 비동기함수가 실행되면 Task Queue로 넘어간다고 했는데 이때 실행된 함수가 어떤 함수냐에 따라 어느 Queue로 보낼지 나눠진다.
setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI렌더링 -> Macro
promise.nextTick, Promise, Object.observe, MutationObserver, queueMicrotask -> Micro task
결과 적으로 말하면 Microtask Queue -> Macro Queue 순의 우선순위를 가진다.
이는 직접 코드로 확인해 볼 수 있다.
// 1. 실행
console.log("script start");
// 2. task queue로 전달
setTimeout(function () {
// 10. task 실행
console.log("setTimeout");
}, 0);
//3. microtask queue로 전달
Promise.resolve()
.then(function () {
// 5. microtask 실행
console.log("promise1");
}) // 6. microtask queue로 전달
.then(function () {
// 7. microtask 실행
console.log("promise2");
});
//4. 실행
console.log("script end");
보면 우선순위 대로 console이 찍히는 것을 볼 수 있다.
Microtask queue에 있는 Promise가 먼저 콜스택으로 들어가고, 콜백함수가 실행 된 후, setTimeout task queuue가 콜스택으로 들어가 실행된다.
일반 Promise가 어떻게 실행되는 지는 위에서 봤다. Async/Await 쓸때는 조금 다르게 실행된다.
const one = () => Promise.resolve("One")
async function myFunc() {
console.log("In function")
const res = await one();
console.log(res)
}
console.log("before")
myFunc();
console.log("After")
async 함수에서는 await를 만나면 함수가 중단된다.
Promise의 body는 계속 실행중인 상태다.
이해가 안간다면
애니메이션 https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke
을 통해 이해를 더 잘 할 수 있다.