Post

이벤트 루프(Event Loop)

이벤트 루프(Event Loop)

이벤트 루프(Event Loop)란?

자바스크립트의 이벤트 루프는 싱글 스레드 기반 언어임에도 비동기 처리를 가능하게 하는 핵심 메커니즘이다.
즉, 한 번에 하나의 작업만 처리할 수 있는 자바스크립트가 동시에 여러 일을 하는 것처럼 보이게 만드는 비밀 !


자바스크립트의 실행 구조

자바스크립트 엔진은 크게 세 가지 구성요소로 나뉜다.

  1. 콜 스택(Call Stack)
    → 실행 중인 함수들이 쌓이는 공간.
    함수가 호출되면 스택에 쌓이고, 실행이 끝나면 스택에서 제거.

  2. 힙(Heap)
    → 객체가 저장되는 메모리 영역
    비동기 동작과 직접적인 관련은 없지만, 참조되는 데이터들이 여기에 존재

  3. 태스크 큐(Task Queue)
    → 비동기 작업이 완료된 후, 실행 대기 중인 콜백 함수들이 저장되는 공간
    이벤트 루프가 콜 스택이 비었을 때 이 큐의 작업을 꺼내 실행

-> 이벤트 루프 : 콜 스택이 비어 있을 때, 태스크 큐의 작업을 가져와 실행하는 ‘조정자’ 역할


이벤트 루프의 동작 원리

  1. 콜 스택이 비어 있는지 확인
  2. 비어 있다면, 태스크 큐에서 대기 중인 콜백을 하나 꺼내 실행
  3. 다시 1번으로 돌아감

이 과정을 끊임없이 반복하면서 자바스크립트는 동기 작업과 비동기 작업을 적절히 조율


예시: setTimeout(callback, 0)

1
2
3
4
5
6
7
console.log("시작");

setTimeout(() => {
  console.log("타이머 완료");
}, 0);

console.log("");

실행 결과 :

1
2
3
시작  
끝  
타이머 완료

setTimeout(callback, 0)즉시 실행되지 않는다.
0ms 뒤에 실행된다는 뜻이 아니라, 콜 스택의 모든 동기 작업이 완료된 후에 실행 대기 큐에 등록된다는 의미이다.

즉, 1️⃣ A가 출력 →
2️⃣ setTimeout의 콜백이 웹 API로 이동
3️⃣ C가 출력 →
4️⃣ 콜 스택이 비면 이벤트 루프가 큐에 있던 B를 실행
이 순서로 진행된다.

event loop


태스크 큐의 종류

구분예시실행 시점우선순위
매크로태스크(Macro Task)setTimeout, setInterval, setImmediate각 이벤트 루프 사이클마다 한 번 실행낮음
마이크로태스크(Micro Task)Promise.then, MutationObserver, queueMicrotask매크로태스크 직후 실행높음

이벤트 루프는 매크로태스크를 하나 실행할 때마다, 그 직후 마이크로태스크 큐에 쌓인 모든 작업을 먼저 처리한다.


⚖️ 매크로태스크 vs 마이크로태스크 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
console.log("시작");

setTimeout(() => {
  console.log("매크로태스크");
}, 0);

Promise.resolve().then(() => {
  console.log("마이크로태스크");
});

console.log("");

// 출력 결과
// 시작
// 끝
// 마이크로태스크
// 매크로태스크

이처럼 Promise의 then() 콜백은 setTimeout보다 먼저 실행된다.
즉, 마이크로태스크 큐는 매크로태스크보다 우선순위가 높다는 점이 중요하다.


이벤트 루프의 순서 요약

1️⃣ 콜 스택의 동기 코드 실행
2️⃣ 콜 스택이 비면 마이크로태스크 큐의 모든 작업 실행
3️⃣ 매크로태스크 큐에서 하나의 작업 실행
4️⃣ 다시 2번으로 반복


💡 정리

개념역할
콜 스택현재 실행 중인 함수 관리
웹 API비동기 작업 처리 영역
마이크로태스크 큐우선순위가 높은 비동기 콜백 대기
매크로태스크 큐일반 비동기 콜백 대기
이벤트 루프콜 스택과 큐를 연결하는 조정자

이벤트 루프는 자바스크립트가 싱글 스레드임에도 비동기를 효율적으로 처리할 수 있는 핵심 원리이다.
이 덕분에 자바스크립트는 UI 렌더링, 사용자 입력, 네트워크 요청 등을 블로킹 없이 처리할 수 있다.


END

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