프로미스에 대해 공부하다가, 마이크로 태스크 큐에 대해 알게되었는데 우선순위가 궁금해져 자료들을 찾아보았다.
이벤트 루프
이벤트 루프란 태스크가 들어오길 기다렸다가 콜 스택이 비어 있는 것을 확인하면 이를 콜스택으로 옮기는 자바스크립트 엔진 내부에서 끊임 없이 돌아가는 루프이다.
태스크 큐와 마이크로 태스크 큐
2개의 큐 모두 콜백함수가 들어간다는 점에서 동일하지만, 어떤 함수를 실행하여 생성된 콜백함수냐에 따라 들어가는 방향이 달라진다.
- 콜백함수를 태스크 큐에 넣은 함수들
- setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O , UI 렌더링, 이벤트 리스너
- 콜백함수를 마이크로태스크 큐에 넣는 함수들
- Promise, Object.observe, MutatationObserver
이렇게 함수에 따라 콜백함수가 달리 큐에 들어가는 것을 알게되었다. 그러면 태스크 큐와 마이크로 태스크 큐에 있는 콜백함수중에 어느 것을 우선적으로 콜 스택으로 옮길까?
누가 먼저 일까?
마이크로 태스크 큐의 콜백 함수가 태스크 큐의 콜백 함수보다 우선적으로 실행된다.
이벤트 루프는 마이크로 태스크 큐의 콜백 함수들을 처리한 다음, 태스크 큐의 콜백 함수를 처리한다.
console.log('콜 스택!');
setTimeout(() => console.log('태스크 큐!'), 0);
Promise.resolve().then(() => console.log('마이크로태스크 큐!'));
위 코드의 결과는 다음과 같다.
콜 스택!
마이크로태스크 큐!
태스크 큐!
이제 위 코드의 동작과정을 시각자료로 살펴보자.
콜 스택의 최상위에 있는 console.log가 호출 된다.
setTimeout 함수가 호출되고 Web API 가 타이머 만큼 대기한후 콜백함수를 태스크 큐로 옮긴다.
그 후 Promise resolve 가 실행되어 마이크로 태스크 큐로 콜백 함수가 이동한다.
이때 콜 스택이 비어있다. 마이크로 태스크 큐의 콜백 함수가 우선적으로 실행되므로 Promise 콜백이 콜 스택으로 이동한다.
이제 태스크 큐의 콜백이 이벤트 루프에 의해 콜 스택으로 옮겨지고 실행된다.
더 나아가 보자.
다음글에 따르면, 마이크로 태스크는 실행되면서 새로운 마이크로 태스크 큐를 추가하게 되는데 새롭게 추가된 마이크로 태스크도 큐가 빌 때까지 계속해서 실행된다고 한다.
그래서 궁금해서 확인해봤다. 맞더라.
console.log('콜 스택!');
setTimeout(() => console.log('태스크 큐!'), 0);
Promise.resolve()
.then(() => {
console.log('마이크로태스크 큐!')
Promise.resolve()
})
.then(()=>console.log('마이크로태스크 큐!'))
참고 자료
'FrontEnd > JS' 카테고리의 다른 글
this (0) | 2023.05.30 |
---|---|
프로미스 (5) | 2023.05.30 |
실행 컨텍스트 (0) | 2023.05.25 |
자바스크립트 엔진의 최적화 기법 (1) | 2023.04.17 |
자바스크립트 이벤트 루프 (2) | 2022.09.23 |