TIL#43 JS) 이벤트 루프의 Queue

luneah·2021년 12월 11일
0

JavaScript

목록 보기
16/16
post-thumbnail

Event Loop는 브라우저에 존재하는 여러 Queue들에 우선순위를 부여해 어떤 task를 먼저 수행할지 결정한다. 그런데 아래의 그림을 보면 태스크 큐 외에도 다른 큐들이 있다. 그래서 이에 대해서도 정리해보려고 한다.


Event Loop의 Queue

Task Queue

우리가 기존에 알고 있던 Task Queue 는 뒤에서 설명한 Microtask Queue 와 구별하기 위해 Macrotask Queue 라고도 부른다.

Task Queue 는 Web API 가 수행한 비동기 함수를 넘겨받아 Event Loop 가 해당 함수를 Call Stack 에 넘겨줄 때까지 비동기 함수들을 쌓아놓는 곳이다.

이 큐는 setTimeout(), setInterval(), setImmediate()와 같은 task를 넘겨받는다.

Microtask Queue

Microtask Queue는 Promise나 async/await, process.nextTick, Object.observe, MutationObserver과 같은 비동기 호출을 넘겨받는다. Microtask의 우선순위는 일반 task(또는 Macrotask)보다 더 높다.

아래 예시처럼, Promise 로 비동기 호출을 하면 해당 작업은 Microtask Queue 에 쌓이게 되는데, Microtask 는 setTimeout 과 같은 일반 Task 보다 높은 우선순위를 가지고 있어서, Promise 함수의 내용이 setTimeout 함수의 내용보다 더 먼저 출력되는 것을 확인할 수 있다.

여기를 클릭하면 아래 코드의 동작 과정을 애니메이션으로 확인할 수 있다.

// 1. 실행
console.log('script start')

// 2. task queue로 전달
setTimeout(function() {
  // 8. 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')

1. Promise

Promise가 Microtask Queue로 전달되는 과정


2. async/await

async/await이 Microtask Queue로 전달되는 과정

ㄴ myFunc 함수 안의 두번째 줄이 실행되었을 때, one 함수는 콜 스택에서 pop되어 promise를 반환한다. → promise가 반환되었을 때 마주하는 것은 await 키워드인데, 이 경우 async 함수의 실행은 미뤄진다. → async 함수의 나머지 부분들을 실행하는 것은 Microtask Queue로 넘겨진다.


Animation Frames

Animation Frames는 requestAnimationFrame과 같이 브라우저 렌더링과 관련된 task를 넘겨받는 Queue이다. 우선 순위는 Microtask보다는 낮고, (Macro)Task보다는 높다.

// 1. 실행
console.log("script start");

// 2. task queue로 전달
setTimeout(function () {
  // 10. task 실행
  console.log("setTimeout");
}, 0);

//3. microtask queue로 전달
Promise.resolve()
  .then(function () {
    // 6. microtask 실행
    console.log("promise1");
  }) // 7. microtask queue로 전달
  .then(function () {
    // 8. microtask 실행
    console.log("promise2");
  });

//4. AnimationFrame으로 전달
requestAnimationFrame(function () {
  //9. animation frame 실행
  console.log("animation");
});

//5. 실행
console.log("script end");

···

✔️ 이벤트 루프가 비동기 작업을 처리하는 우선순위
Microtask Queue > Animation Frames > Task Queue

이벤트 루프는 Microtask Queue나 Animation Frames를 방문할 때는, 큐 안에 있는 모든 작업들을 수행하지만, Task Queue를 방문할 때는 한 번에 하나의 작업만 call stack으로 전달하고 다른 Queue를 순회한다.

profile
하늘이의 개발 일기

0개의 댓글