본문 바로가기
javascript/모던 자바스크립트 Deep Dive

이벤트 루프(Event Loop)와 태스크 큐(Task Queue)

by yongfront 2024. 2. 21.
반응형
SMALL

이벤트 루프(Event Loop)와 태스크 큐(Task Queue)는 JavaScript의 비동기 처리 모델을 이해하는 데 중요한 개념입니다. JavaScript는 싱글 스레드 언어이지만, 이벤트 루프와 태스크 큐를 통해 비동기 작업을 효율적으로 관리하고 실행할 수 있습니다.

이벤트 루프

이벤트 루프는 프로그램의 실행 흐름을 제어하는 메커니즘으로, 호출 스택(Call Stack)이 비어 있을 때 태스크 큐에 대기 중인 다음 작업(태스크)을 호출 스택으로 이동시키고 실행합니다. 이 과정은 프로그램이 종료될 때까지 반복됩니다.

  • 호출 스택(Call Stack): 실행 중인 함수의 호출 기록을 저장하는 스택 구조입니다. 현재 실행 중인 함수가 완료되면 스택에서 제거(pop)되고, 새로운 함수가 호출될 때 스택에 추가(push)됩니다.
  • 태스크 큐(Task Queue): 비동기 작업의 콜백 함수나 이벤트 핸들러가 실행을 기다리는 대기열입니다. 이벤트 루프는 호출 스택이 비었을 때 이 큐에서 작업을 가져와 실행합니다.

태스크 큐

태스크 큐는 실제로 여러 종류가 있으며, 가장 대표적인 것은 **매크로 태스크 큐(Macro Task Queue)**와 **마이크로 태스크 큐(Micro Task Queue)**입니다.

  • 매크로 태스크: setTimeout, setInterval, setImmediate(Node.js), I/O 작업 등의 콜백이 이 큐에 추가됩니다.
  • 마이크로 태스크: Promise, MutationObserver의 콜백이 이 큐에 추가됩니다. 마이크로 태스크 큐는 매크로 태스크 큐보다 우선적으로 처리됩니다.

이벤트 루프의 동작 과정

  1. 호출 스택 확인: 현재 호출 스택이 비어 있는지 확인합니다.
  2. 마이크로 태스크 처리: 마이크로 태스크 큐에 작업이 있다면, 모든 마이크로 태스크를 처리합니다.
  3. 렌더링: 브라우저의 경우, 화면 렌더링이 필요한 경우 이 시점에서 렌더링 작업을 수행합니다.
  4. 매크로 태스크 처리: 매크로 태스크 큐에서 하나의 작업을 가져와 호출 스택에 추가하고 실행합니다. 실행이 완료되면 다시 마이크로 태스크 큐를 확인하여 추가 작업이 있는지 확인합니다.
  5. 반복: 위 과정을 반복합니다.

이벤트 루프와 태스크 큐의 메커니즘 덕분에 JavaScript는 비동기 작업을 효과적으로 관리할 수 있으며, 이는 웹 애플리케이션에서 비동기 API 호출, UI 업데이트, 이벤트 처리 등 다양한 비동기 작업을 가능하게 합니다.

 

아래는 이벤트 루프와 태스크 큐의 작동 원리를 설명하는 간단한 예시 코드입니다. 이 예제는 setTimeout (매크로 태스크), Promise (마이크로 태스크), 그리고 일반적인 동기 코드의 실행 순서를 보여줍니다.

console.log('스크립트 시작');

setTimeout(function() {
  console.log('setTimeout 실행');
}, 0);

Promise.resolve().then(function() {
  console.log('Promise 실행');
});

console.log('스크립트 종료');

실행 순서 설명

  1. 스크립트 시작을 출력합니다. (동기 코드)
  2. **setTimeout**은 0밀리초의 지연 시간을 가지지만, 이벤트 루프와 태스크 큐의 메커니즘으로 인해 즉시 실행되지 않고, 매크로 태스크 큐에 추가됩니다.
  3. **Promise**는 마이크로 태스크이며, **then**에 제공된 콜백은 마이크로 태스크 큐에 추가됩니다. 마이크로 태스크는 현재 실행 중인 스크립트가 완료된 직후, 매크로 태스크보다 먼저 실행됩니다.
  4. 스크립트 종료를 출력합니다. (동기 코드)
  5. 현재 실행 스택이 비었으므로, 이벤트 루프는 마이크로 태스크 큐를 확인하고, Promise 실행을 출력합니다.
  6. 모든 마이크로 태스크가 처리된 후, 이벤트 루프는 매크로 태스크 큐에서 **setTimeout**의 콜백을 실행 스택으로 옮겨 setTimeout 실행을 출력합니다.

예상 출력 결과

스크립트 시작
스크립트 종료
Promise 실행
setTimeout 실행

이 예시는 JavaScript에서 동기 코드가 우선 실행되고, 이후 비동기 작업(Promise, setTimeout)이 어떤 순서로 처리되는지를 보여줍니다. 마이크로 태스크(Promise)는 현재 스크립트 실행이 종료된 직후에 바로 처리되며, 매크로 태스크(setTimeout)는 그 다음에 처리됩니다. 이러한 이벤트 루프의 동작 방식은 비동기 작업을 효율적으로 관리하고, 원활한 사용자 경험을 제공하는 웹 애플리케이션을 만드는 데 핵심적인 역할을 합니다.

728x90
반응형
LIST