이벤트 루프(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의 콜백이 이 큐에 추가됩니다. 마이크로 태스크 큐는 매크로 태스크 큐보다 우선적으로 처리됩니다.
이벤트 루프의 동작 과정
- 호출 스택 확인: 현재 호출 스택이 비어 있는지 확인합니다.
- 마이크로 태스크 처리: 마이크로 태스크 큐에 작업이 있다면, 모든 마이크로 태스크를 처리합니다.
- 렌더링: 브라우저의 경우, 화면 렌더링이 필요한 경우 이 시점에서 렌더링 작업을 수행합니다.
- 매크로 태스크 처리: 매크로 태스크 큐에서 하나의 작업을 가져와 호출 스택에 추가하고 실행합니다. 실행이 완료되면 다시 마이크로 태스크 큐를 확인하여 추가 작업이 있는지 확인합니다.
- 반복: 위 과정을 반복합니다.
이벤트 루프와 태스크 큐의 메커니즘 덕분에 JavaScript는 비동기 작업을 효과적으로 관리할 수 있으며, 이는 웹 애플리케이션에서 비동기 API 호출, UI 업데이트, 이벤트 처리 등 다양한 비동기 작업을 가능하게 합니다.
아래는 이벤트 루프와 태스크 큐의 작동 원리를 설명하는 간단한 예시 코드입니다. 이 예제는 setTimeout (매크로 태스크), Promise (마이크로 태스크), 그리고 일반적인 동기 코드의 실행 순서를 보여줍니다.
console.log('스크립트 시작');
setTimeout(function() {
console.log('setTimeout 실행');
}, 0);
Promise.resolve().then(function() {
console.log('Promise 실행');
});
console.log('스크립트 종료');
실행 순서 설명
- 스크립트 시작을 출력합니다. (동기 코드)
- **setTimeout**은 0밀리초의 지연 시간을 가지지만, 이벤트 루프와 태스크 큐의 메커니즘으로 인해 즉시 실행되지 않고, 매크로 태스크 큐에 추가됩니다.
- **Promise**는 마이크로 태스크이며, **then**에 제공된 콜백은 마이크로 태스크 큐에 추가됩니다. 마이크로 태스크는 현재 실행 중인 스크립트가 완료된 직후, 매크로 태스크보다 먼저 실행됩니다.
- 스크립트 종료를 출력합니다. (동기 코드)
- 현재 실행 스택이 비었으므로, 이벤트 루프는 마이크로 태스크 큐를 확인하고, Promise 실행을 출력합니다.
- 모든 마이크로 태스크가 처리된 후, 이벤트 루프는 매크로 태스크 큐에서 **setTimeout**의 콜백을 실행 스택으로 옮겨 setTimeout 실행을 출력합니다.
예상 출력 결과
스크립트 시작
스크립트 종료
Promise 실행
setTimeout 실행
이 예시는 JavaScript에서 동기 코드가 우선 실행되고, 이후 비동기 작업(Promise, setTimeout)이 어떤 순서로 처리되는지를 보여줍니다. 마이크로 태스크(Promise)는 현재 스크립트 실행이 종료된 직후에 바로 처리되며, 매크로 태스크(setTimeout)는 그 다음에 처리됩니다. 이러한 이벤트 루프의 동작 방식은 비동기 작업을 효율적으로 관리하고, 원활한 사용자 경험을 제공하는 웹 애플리케이션을 만드는 데 핵심적인 역할을 합니다.
'javascript > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
XMLHttpRequest (0) | 2024.02.21 |
---|---|
AJAX(Asynchronous JavaScript and XML) (0) | 2024.02.21 |
동기 처리(Synchronous)와 비동기 처리(Asynchronous) (0) | 2024.02.21 |
디바운스(Debounce)와 스로틀(Throttle) (0) | 2024.02.21 |
타이머 (0) | 2024.02.21 |