Home 이벤트 루프 마이크로 태스크 큐와 매크로 태스크 큐
Post
Cancel

이벤트 루프 마이크로 태스크 큐와 매크로 태스크 큐

자바스크립트 이벤트 루프에 대해서 단순히 개념만 알고 있었는데, 최근에 마이크로 태스크 큐와 매크로 테스크 큐의 차이점을 알게되었다.

✏️ 이벤트 루프란?

자바스크립트에 대해서 공부한다면 흔하디 흔하지만 그만큼 중요한 개념인 이벤트 루프다.

자바스크립트는 기본적으로 실행 흐름은 기본적으로 이벤트 루프에 기반한다. 싱글 스레드임에도 멀티 처리가 가능한 이유는 이 이벤트 루프가 있기에 가능하다.

만약 이벤트 루프에 기반하지 않고 단순 싱글 스레드 언어였다면, 대용량 데이터 처리 및 로딩, 다운로드, 파일 처리 등 관련 작업에서 메인 스레드가

블로킹되어 다음 태스크까지 이전 작업이 완료될 떄까지 기다려야 할 것이다.

이벤트 루프는 태스크가 들어올 때까지 기다렸다가 들어오면 이를 수행하고, 태스크가 없다면 대기하는 끊임없는 루프를 반복한다.

1. 콜 스택에서 동기 코드 실행

모든 동기적인 코드는 콜 스택에 쌓이고 순서대로 즉시 실행된다. 이 과정에서 setTimeout이나 fetch 같은 비동기 함수를 만난다면 자바스크립트는 이를 직접 처리하지 않고 Web API에게 “이 일 좀 처리해줘!”라고 요청한 뒤 바로 다음 동기 코드로 넘어간다.

2. Web API의 비동기 작업 처리 (백그라운드)

Web API는 요청받은 작업을 백그라운드에서 처리한다. (예: setTimeout의 경우 타이머를 세고 fetch의 경우 네트워크 요청을 보냄) 이 작업은 메인 스레드와 별개로 진행된다.

3. 완료된 작업의 콜백 함수를 큐로 이동

Web API가 작업을 완료하면 약속되었던 콜백 함수(예: setTimeout의 첫 번째 인자, .then() 안의 함수)를 적절한 큐로 보낸다.

4. 이벤트 루프의 감지

이벤트 루프는 계속해서 “콜 스택이 비어 있는가?”를 확인한다.

5. 콜 스택이 비었을 때 큐에서 작업 가져오기

콜 스택이 비면, 이벤트 루프는 가장 먼저 큐를 확인한다. 큐 안에 있는 모든 작업을 순서대로 꺼내와 콜 스택으로 옮겨 실행한다. 큐가 완전히 빌 때까지 이 과정을 반복한다.

6. 반복

하나의 태스크 실행이 끝나면 콜 스택은 다시 비워진다. 그러면 이벤트 루프는 다시 5번 과정을 반복한다.

만약 다음과 같은 상황이라면 실행 순서는 어떻게 될까?

1
2
3
4
5
6
7
8
9
10
11
console.log("1. 동기 코드 시작");

setTimeout(() => {
  console.log("2. setTimeout");
}, 0);

Promise.resolve().then(() => {
  console.log("3. Promise.then");
});

console.log("4. 동기 코드 끝");

마이크로 태스크 큐와 매크로 태스크 큐의 개념이 없어 당연히 1 -> 4 -> 2 -> 3 으로 실행될 것이라 예상했다.

각 차이점은 다음과 같다.

마이크로 태스크 큐 (잡 큐)

마이크로 태스크 큐의 주요 작업은 Promise.then/catch/finally, async/await, MutationObserver, queueMicrotask 등이 있다. 현재 실행 중인 스크립트(동기 코드)가 끝난 직후 다음 매크로태스크가 시작되기 전에 실행되고, 태스크 큐보다 우선 순위가 높다.

매크로 태스크 큐 (태스크 큐, 이벤트 큐)

매크로 태스크 큐의 주요 작업은 setTimeout, setInterval, setImmediate, I/O, UI 렌더링 등이 있다. 하나의 매크로태스크 실행 후 마이크로태스크 큐가 비워질 때까지 기다린다.

즉, 실행 순서는 다음과 같다.

실행 흐름

  1. 동기 코드 실행: 먼저 콜 스택에 있는 모든 동기적인 코드를 순서대로 실행

  2. 마이크로태스크 처리: 콜 스택이 비워지면 마이크로태스크 큐에 있는 모든 작업을 꺼내와 순서대로 실행. 이 과정에서 새로운 마이크로태스크가 추가된다면 그 작업 역시 이번 사이클에서 전부 실행될 때까지 계속함

  3. UI 렌더링: 브라우저는 변경된 사항을 화면에 렌더링할지 결정합

  4. 매크로태스크 처리: 마이크로태스크 큐가 완전히 비워진 후에 매크로태스크 큐에서 가장 오래된 작업 하나를 꺼내와 실행

  5. 반복: 작업이 끝나면 다시 2번 과정으로 돌아가 위 과정을 반복

하나의 매크로태스크가 실행된 후에는 쌓여있는 모든 마이크로태스크를 전부 처리하고 나서야 다음 매크로태스크로 넘어갈 수 있다. 이 때문에 마이크로태스크는 매크로태스크보다 더 우선 순위가 높다.

This post is licensed under CC BY 4.0 by the author.