
마이크로태스크 큐와 태스크 큐, 두 큐 모두 콜백 함수가 들어간다는 공통점이 있다.
하지만 어떤 함수를 실행하느냐에 따라 어느 큐로 들어가는지가 달라진다.
이름은 Queue(큐)지만, 일반적인 자료구조의 큐와는 조금 다르다.
각 큐 내부에서는 FIFO(먼저 들어온 것이 먼저 나간다) 방식으로 동작하지만,
두 큐 사이에는 처리 우선순위가 존재한다. 이벤트 루프는 항상 마이크로태스크 큐를 먼저 비운 뒤에야 태스크 큐를 처리한다.
브라우저 / Node.js 공통
setTimeoutsetIntervalrequestAnimationFrameNode.js 전용
setImmediate브라우저 / Node.js 공통
Promise (.then, .catch, .finally)MutationObserverNode.js 전용
process.nextTick이벤트 루프는 콜 스택이 비워지면 큐에서 콜백을 꺼내 실행한다.
이때 항상 마이크로태스크 큐를 먼저, 완전히 비운 뒤에 태스크 큐로 넘어간다.
setTimeout(() => console.log('task'), 0);
Promise.resolve().then(() => console.log('microtask'));
// 출력 순서:
// microtask
// task
setTimeout의 딜레이가 0ms여도 Promise의 콜백이 항상 먼저 실행되는 이유가 바로 이것이다.
마이크로태스크 큐는 큐가 완전히 빌 때까지 계속 처리된다.
만약 마이크로태스크 내부에서 새로운 마이크로태스크를 계속 추가한다면,
태스크 큐는 영원히 실행되지 않을 수 있다. 이를 starvation(기아 현상) 이라고 한다.
function infiniteMicrotask() {
Promise.resolve().then(() => {
console.log('microtask');
infiniteMicrotask(); // 마이크로태스크를 계속 추가
});
}
setTimeout(() => console.log('task'), 0);
infiniteMicrotask();
// 'task'는 영원히 출력되지 않는다
자바스크립트의 이벤트 루프는 콜 스택이 비워지면 두 가지 큐, 즉 마이크로태스크 큐와 태스크 큐에서 콜백 함수를 꺼내 실행합니다. Promise의 콜백은 마이크로태스크 큐에, setTimeout의 콜백은 태스크 큐에 들어가며, 이벤트 루프는 항상 마이크로태스크 큐를 완전히 비운 뒤 태스크 큐를 처리합니다. 따라서 딜레이가 동일하더라도 Promise의 콜백이 setTimeout의 콜백보다 먼저 실행됩니다. 한 가지 주의할 점은, 마이크로태스크가 재귀적으로 계속 추가될 경우 태스크 큐가 아예 실행되지 못하는 starvation 현상이 발생할 수 있다는 것입니다.
댓글을 작성하려면 로그인이 필요합니다.
아직 작성된 댓글이 없어요. 첫 댓글을 남겨주세요!