매크로태스크 큐와 마이크로태스크 큐
신현호
목차
서론
#저번 포스팅에서 설명했던 태스크 큐에 대해 더 다루어보려고 합니다.
매크로태스크 큐와 마이크로태스크 큐
#태스크 큐는 사실 크게 두 가지 구성으로 되어있습니다.
- 매크로 태스크 큐 (그냥 태스크 큐라고 부르기도 합니다)
- 마이크로 태스크 큐
매크로 태스크 큐는 말 그대로 매크로 태스크들로 이루어진 큐 이고, 마이크로 태스크 큐 또한 동일합니다.
위의 그림을 보시면 매크로 태스크 큐와 마이크로 태스크 큐의 차이를 알 수 있습니다.
사진을 보면 매크로 태스크는 최초에 콜 스택에 존재하는 태스크를 제외하면 마이크로 태스크 큐에 존재하는 태스크들이 모두 완료되기 전까지는 실행되지 않습니다.
또, 마이크로 태스크들은 실행하면서 새로운 마이크로 태스크를 큐에 추가시킬 수 있습니다. 이 때 추가된 태스크들도 계속해서 실행됩니다.
반면에, 매크로 태스크가 실행되며 추가한 매크로 태스크들은 다음 이벤트 루프가 실행되기 전까지는 실행되지 않습니다.
한마디로, 이벤트 루프는 다음과 같은 과정을 반복하게 되는 것 입니다.
- 콜 스택이 비었는지 체크합니다.
- 비어 있다면, 마이크로 태스크 큐가 빌 때까지 작업들을 하나씩 콜 스택에 추가합니다. (마이크로 태스크 큐가 비어있다면 2/3번 과정은 스킵)
- 렌더링 작업이 필요하다면 렌더링을 수행합니다.
- 매크로 태스크 큐로부터 실행 가능한 가장 오래된 태스크를 받아와 콜스택에 추가합니다.
이를 통해 마이크로 태스크가 모두 끝나기 전까지는 렌더링이 수행되지 않는다는 점을 기억해주시면 좋을 것 같습니다!
다음으로, 매크로 태스크와 마이크로 태스크에는 뭐가 있는지 알아보도록 하겠습니다.
매크로 태스크
#매크로 태스크에 해당하는 작업들은 다음과 같습니다.
- setTimeout() / setInterval() / setImmediate() 와 같은 비동기 함수들
- DOM 이벤트 콜백
- 스크립트 로딩 등..
마이크로 태스크
#마이크로 태스크에 해당하는 작업들은 다음과 같습니다.
- .then() / .catch() / .finally() 와 같은 Promise 핸들러
- async 함수들 등..
예시
#단순 설명만으로 이해하기는 힘들 수 있으니 예시를 들어보도록 하겠습니다.
js
console.log('Start!') // 1
setTimeout(() => console.log('setTimeout Finish')) // 2
Promise.resolve()
.then(() => console.log('First Promise')) // 3
.then(() => console.log('Second Promise')) // 4
과연 출력의 순서는 어떻게 될까요?
정답은 바로 다음과 같습니다.
js
Start! // 1
First Promise // 3
Second Promise // 4
setTimeout Finish // 2
이유는 다들 아시겠죠? 흐름을 설명해보자면
- 시작할 때 console.log('Start!') 가 실행됨
- setTimeout 작업이 매크로 태스크 큐에 추가됨
- Promise.resolve()를 읽으며 .then() 작업이 매크로 태스크 큐에 추가됨
- .then() 작업을 모두 수행하고 매크로 태스크 큐에 있던 setTimeout()이 실행됨
따라서 출력 순서는 1 -> 3 -> 4 -> 2 가 되는 것 입니다!
참고
#신현호
Frontend Developer
프론트엔드 개발자를 꿈꾸고 있는 대학생입니다. 끊임없이 배우고 성장하는 개발자가 되기 위해 노력하고 있습니다.