자바스크립트 (JS) 이벤트루프(2) MicroTask Queue

Fizz·2022년 9월 21일
0
post-thumbnail

이벤트 루프 2탄!! Task Queue 말고 어떤 Queue???

Micro Task 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

어떤 Queue가 높은 우선순위를 가질까?

결과 적으로 말하면 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가 콜스택으로 들어가 실행된다.

Async Await??

일반 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")

  1. 먼저 동기인 before가 콜스택에 들어가고 출력된다
  2. myFunc 함수를 호출하고 body를 실행한다. 그 후 conole.log를 콜스택에 넣고 출력한다.
    안의 두번째 줄이 실행되었을 때, one 함수는 콜 스택에서 pop되어 promise를 반환한다.
    promise가 반환되었을 때 await 키워드가 있어 async 함수의 실행은 미뤄진다.
    그리고 async 함수의 나머지 부분들을 실행하는 것은 microtask Queue로 넘겨진다.
    async 함수에서 나와서(jumps out) async함수를 호출한 실행 컨텍스트로 돌아가서 마저 실행된다
    (위의 예시에서는 전역 컨텍스트로 돌아가서 함수 실행을 한다.)
    그 후 console.log가 스택에 더해져 실행되고 출력 된 후 실행 컨텍스트에 task가 없는 걸 확인하고
    Micro Task queue를 확인해 myFunc가 콜스택으로 가 이전에 await을 보고 중단된 나머지를 실행해 One이 출력된다.

위의 과정으로 Promise.then과 async 함수의 차이점을 알 수 있다

async 함수에서는 await를 만나면 함수가 중단된다.
Promise의 body는 계속 실행중인 상태다.

이해가 안간다면
애니메이션 https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke
을 통해 이해를 더 잘 할 수 있다.

profile
성장하고싶은 개발자

0개의 댓글