이벤트 루프(Event Loop)

FE-leejinw·2026년 4월 5일

javascript

목록 보기
10/10

주제: Event Loop & Asynchronous Internal (이벤트 루프와 비동기 내부 구조)


💭 오늘의 회고

그동안 async/awaitPromise를 수만 번 써오면서도, 정작 이놈들이 브라우저 안에서 어떤 순서로 줄을 서서 실행되는지는 대충 '비동기니까 나중에 되겠지'라고만 막연하게 생각했던 것 같다. 오늘 이벤트 루프의 설계도를 밑바닥부터 뜯어보니, 내가 짠 코드들이 왜 그런 순서로 움직였는지 비로소 퍼즐이 맞춰지는 기분이다. 5년 차라는 연차에 걸맞게 '동작 원리'를 아는 것이 얼마나 중요한지 새삼 깨달았다.


🏗️ 내 머릿속에 박아넣은 구조도

자바스크립트 엔진은 '싱글 스레드'라는 제약을 극복하기 위해 외주(Web API)철저한 대기열(Queue) 시스템을 활용한다.

 [ 메인 엔진 (Stack) ]          [ 외주 업체 (Web APIs) ]
          │                            │
    함수 실행! (LIFO)  ──────▶   타이머, 네트워크 요청 등
          │           (위임)            │
          ▼                            ▼
 [ 이벤트 루프 (Event Loop) ] ◀─── 작업 완료 후 콜백 전달
          │
          ▼
 [ 대기열 (Queues) ]
  1. Microtask Queue (VIP)  : Promise, async/await (싹쓸이 처리)
  2. Render Tree Update     : UI 업데이트 (화면 그리기)
  3. Task Queue (General)   : setTimeout, setInterval (하나씩 처리)

🔍 오늘 깨달은 핵심 로직 (The Tick)

이벤트 루프는 쉼 없이 돌면서 딱 네 가지만 확인한다. 이 우선순위가 실무의 핵심이다.

  1. Stack이 비었는가?
    • 엔진이 지금 당장 할 일이 없어야 루프가 다음 단계로 넘어간다.
  2. VIP부터 모신다 (Microtask Queue)
    • Promise.then 같은 애들이 기다리고 있다면, 큐가 완전히 빌 때까지 하나도 남김없이 Stack으로 옮겨서 실행한다.
    • 실행 도중에 또 Microtask가 생기면? 그것까지 다 끝내야 다음으로 넘어간다. (여기서 무한루프 돌면 브라우저가 먹통이 됨)
  3. 화면을 그릴 시간인가? (Render)
    • Microtask를 다 비운 직후, 브라우저는 비로소 화면을 새로 그릴(Paint) 기회를 얻는다.
  4. 일반 손님 처리 (Task Queue)
    * 드디어 setTimeout 같은 콜백을 처리하는데, Microtask와 다르게 딱 하나의 task만 실행하고 다시 1번(Stack 확인)으로 돌아간다.
    (다시 1번으로 돌아가는 플로우 때문에 이벤트 루프 라는 명칭을 사용)

💡 파헤쳐보며 '깨달은' 포인트

  • setTimeout(0)이 0초가 아닌 이유: 아무리 0초라고 해도 얘는 'Task Queue'로 간다. 앞에 쌓인 Microtask(Promise)가 1만 개라면, 걔네가 다 처리될 때까지 얘는 절대로 실행될 수 없다. 즉, 지연 시간은 '실행 시점'이 아니라 'Task Queue에 들어가는 시점'을 의미한다.
  • 성능 최적화의 힌트: UI가 버벅이지 않게 하려면 무거운 로직을 Microtask에 몰아넣지 말고 적절히 쪼개서 Task Queue로 분산시키는 전략이 필요할 것 같다.

🚀 정리

이벤트 루프의 '길'을 이해했으니, 이제 이 길 위에서 변수들이 어떻게 메모리를 점유하고 사라지는지(실행 컨텍스트와 호이스팅)를 파헤쳐 보도록 해보자.
이제 몇 년 내로 시니어 포지션으로 전환하려면 기본기가 더욱 탄탄해야 할 것 같다는 생각이 더욱 피부로 와닿게 되는 시간이었다. 끝.

profile
똑똑하진 않아서 꾸준히라도 할려고 하는 그러한 사람

0개의 댓글