지난 시간엔 콜 스택, 태스크 큐, 이벤트 루프에 대해 알아보며 호출스택과 테스크큐의 관계에 대해 알아보았는데요.
오늘은 Micro task queue에 대해 알아보며 지난번에 했던 태스크 큐와 어떤 차이가 있는지 알아보도록 하겠습니다.
태스크 큐와 마이크로 태스크 큐
먼저 마이크로 태스크 큐는 일반 태스크 보다 좀 더 우선순위를 갖는 태스크 큐라고 보면 됩니다.
2개의 큐 모두 콜백함수가 들어간다는 점에서 동일하지만 어떤 함수를 실행하느냐에 따라 어디로 들어가는지가 달라지게 됩니다.
여기에 큐 (Queue)는 실제 우리가 아는 자료구조의 큐와는 다릅니다. 우선순위 큐 (Priority Queue) 라고 할 수 있는데,
이벤트 루프가 2개의 큐에서 태스크를 꺼내는 조건이 "제일 오래된 태스크" 이기 때문이죠.
태스크 큐는 마이크로 태스크 큐와 매크로 태스크 큐로 나누어지는데 어떤 API를 사용하냐에 따라 둘 중 하나를 사용하게 됩니다.
macrotasks - requestAnimationFrame, I/O, UI rendering, setTimeout, setInterval, setImmediate
microtasks - process.nextTick, Promise, queueMicrotask(f), MutationObserver
동작 형태는 아래와 같습니다.
우리에게 익숙한 함수인 Web API의 setTimeout() 의 콜백함수가 태스크 큐에 들어가고 Promise 의 콜백함수가 마이크로태스크 큐에 들어간다는 것을 알 습니다. 그렇다면 이벤트 루프는 각 콜백함수를 태스크/마이크로태스크 큐에서 꺼내쓰는 것인데, 그렇다면 어떤게 먼저일까요?
마이크로 태스크 큐가 먼저입니다.
이벤트 루프는 마이크로태스크 큐의 모든 태스크들을 처리한 다음, 태스크 큐의 태스크들을 처리하게 됩니다.
따라서, Promise 의 콜백함수가 setTimeout() 의 콜백함수보다 먼저 처리됩니다.
console.log('call stack!');
setTimeout(() => console.log('task queue!'), 0);
Promise.resolve().then(() => console.log('micro task queue!'));
마이크로 태스트 큐의 콜백함수가 먼저 처리되는 것을 알 수 있습니다.
console.log()는 처음 스크립트가 로드될 때 call stack!이라는 태스크가 먼저 태스크 큐에 들어가게 되고,
이벤트 루프가 태스크 큐에서 이 태스크를 가져와 실행하게 되는 것입니다.
그러니까 call stack에서는 이미 GEC(Global Execution Context)가 생성되어 있는 상태에서 call stack! 이라는 태스크를 실행하게 되면 그제서야 GEC에 속한 코드가 실행되는 방식인겁니다.
그럼 위 코드가 어떻게 동작하는 지 그림으로 살펴보도록 하겠습니다.
제일 먼저 "call stack!"이라는 태스크가 태스크 큐에 들어가게 됩니다.
그 후, 이벤트 루프가 그 태스크를 가져와서 로드된 스크립트를 실행시키게 되어 처음에 console.log()가 실행됩니다.
그 다음, setTimeout() 이 콜 스택으로 가고 브라우저가 이를 받아서 타이머를 동작시키게 됩니다.
타이머가 끝나면 setTimeout() 의 콜백함수를 태스크 큐에 넣어 줍니다.
그 다음 Promise 가 콜 스택으로 가고 콜백함수를 마이크로태스크 큐에 넣어 줍니다.
이벤트 루프는 마이크로태스크 큐에서 제일 오래된 태스크인 Promise 의 콜백함수를 가져와 콜 스택에 넣어 줍니다.
Promise 의 콜백함수가 끝나고 태스크 큐에서 제일 오래된 태스크인 setTimeout() 의 콜백함수를 가져와 콜 스택에 넣어줍니다.
setTimeout() 의 콜백함수가 끝나면 콜 스택이 비게 되고 프로그램이 종료됩니다.
지금까지 마이크로태스크가 무엇인지, 태스크 큐와 마이크로태스크가 어떻게 다른지, 이 들을 각각을 어떻게 처리하는지에 대해 알아보았습니다.이런 원리들을 이해하고 사용한다면 비동기 로직을 다룰 때 훨씬 견고하고 예측 가능한 코드를 짤 수 있을 것이라 생각되어 공유 해봅니다. 틀린 부분을 알려주신다면 감사하겠습니다.
'프로그래밍(Basic) > Javascript(TS,Node)' 카테고리의 다른 글
[바미] Factory 패턴 (0) | 2022.10.06 |
---|---|
[바미] Flyweight 패턴 (2) | 2022.10.05 |
[바미] 콜 스택, 태스크 큐, 이벤트 루프 (0) | 2022.07.30 |
[바미] 바벨(Babel)에 대하여 (0) | 2022.07.11 |
[바미] Node SQL 파라미터 적용 방법. (0) | 2022.05.02 |