단북
프론트엔드 기술 면접·자바스크립트 핵심 개념

자바스크립트의 이벤트 루프와 태스크 큐란 무엇인가요?

단일 스레드에서 비동기를 처리하는 이벤트 루프, 콜 스택, 마이크로태스크와 매크로태스크 큐의 우선순위를 정리합니다.

자바스크립트는 단일 스레드라 한 번에 하나의 작업만 처리합니다. 그런데도 타이머·네트워크 요청 같은 비동기 작업을 멈춤 없이 다룰 수 있는 비결이 이벤트 루프(event loop) 입니다.

콜 스택과 큐

  • 콜 스택(call stack) — 현재 실행 중인 함수들이 쌓이는 곳. 동기 코드는 여기서 즉시 실행됩니다.
  • 태스크 큐(매크로태스크)setTimeout, setInterval, I/O, UI 이벤트 콜백이 대기하는 곳.
  • 마이크로태스크 큐Promise.then/catch/finally, queueMicrotask, MutationObserver 콜백이 대기하는 곳.

이벤트 루프는 콜 스택이 비면 큐에서 작업을 꺼내 스택에 올립니다. 각 작업은 run-to-completion, 즉 시작하면 중간에 끊기지 않고 끝까지 실행됩니다.

핵심: 마이크로태스크가 먼저

우선순위가 가장 중요합니다. 이벤트 루프는 매크로태스크 하나를 처리한 뒤, 다음 매크로태스크로 넘어가기 전에 마이크로태스크 큐를 전부 비웁니다. 즉 “모든 마이크로태스크 → 매크로태스크 하나 → 다시 모든 마이크로태스크” 순으로 돕니다.

console.log('1'); // 동기
 
setTimeout(() => console.log('2'), 0); // 매크로태스크
 
Promise.resolve()
  .then(() => console.log('3')) // 마이크로태스크
  .then(() => console.log('4')); // 마이크로태스크
 
console.log('5'); // 동기
 
// 출력: 1 → 5 → 3 → 4 → 2

동기 코드(1, 5)가 먼저 끝나고, 콜 스택이 비면 마이크로태스크(3, 4)를 모두 처리한 다음, 마지막으로 매크로태스크(2)가 실행됩니다. setTimeout(fn, 0)이라도 마이크로태스크보다 늦게 실행되는 이유가 여기에 있습니다.

왜 중요한가

긴 동기 작업은 콜 스택을 오래 점유해 이벤트 루프를 막고, 그동안 UI 렌더링과 클릭 같은 이벤트 처리가 멈춰 화면이 멈춘 듯한 현상이 생깁니다. 무거운 작업을 쪼개거나 워커로 분리해야 하는 이유입니다.

다음 코드의 출력 순서로 옳은 것은?

console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');

이 레슨을 다 읽으셨나요?

완료 표시는 이 브라우저에 저장됩니다.