본문 바로가기

자바스크립트

Event Loop

자바스크립트는 단일 스레드 기반의 언어(Call Stack이 하나)로 한 순간 하나의 작업만을 처리하지만, 동시에 많은 작업을 수행하는 것처럼 보인다. 브라우저의 Web APIs, Event Table, Callback Queue, Event Loop 등(Node에서는 libuv 라이브러리)을 이용해 비동기 방식으로 동작하기 때문이다.

 

자바스크립트 코드 실행 과정

  • Memory Heap : 메모리 할당이 발생하는 곳으로, 우리가 프로그램에 선언한 변수와 함수 등이 담겨 있다.
  • Call Stack : 실행된 코드의 환경을 저장하는 자료구조이다. 함수 호출 시 Call Stack에 push 된다.
  • Web APIs : 브라우저에서 제공하는 API(DOM, Ajax, Timeout 등)이다. Call Stack에서 비동기 함수(setTimeout)가 실행되면 Web API를 호출하고, Web API는 콜백함수를 Callback Queue에 밀어 넣는다.
  • Event Table : 특정 event(timeout, click, mouse move 등)가 발생했을 때 어떤 callback 함수가 호출되야 하는지를 알고 있는 자료구조이다.
  • Callback Queue : 이벤트 발생 시 실행해야 할 콜백함수가 보관되는 영역이다. 예를 들어 setTimeout에서 타이머 완료 후 실행되는 함수(첫 번째 인자), addEventListener에서 click 이벤트가 발생했을 때 실행되는 함수(두 번째 인자) 등이 보관된다.
  • Event Loop : Call Stack과 Callback Queue의 상태를 체크하여, Call Stack이 빈 상태가 되면, Callback Queue의 첫번째 콜백을 Call Stack으로 밀어 넣는다.

자바스크립트 엔진은 대표적으로 Google의 V8 엔진이 있고, 크게 Memory Heap과 Call Stack으로 구성되어 있다. Memory Heap에 사용자가 작성한 코드들이 담겨 있고, V8 엔진에서 코드가 실행되면 그 코드들은 Call Stack에 쌓인다. Stack의 룰에 따라 제일 마지막에 들어온 함수부터 실행되는데, 이때 동기 함수들은 그대로 실행되고 비동기 함수들이 실행된다면 웹 브라우저에서 제공하는 Web API가 호출된다. Web API는 비동기 함수의 콜백 함수를 Callback Queue로 넘겨준다. Call Stack이 비게 되면 Event Loop가 Callback Queue에 있는 콜백 함수를 Call Stack에 넘겨주고 Call Stack에서 콜백함수를 실행한다.

 

이벤트 루프 동작 과정 예시

function main(){
  console.log('A');
  setTimeout(
    function exec(){ console.log('B'); }
  , 0);
	console.log('C');
}

main(); // 실행 결과 A → C → B 순으로 출력된다.

  1. main() 스택에 추가
  2. console.log('A') 스택에 추가, 실행, 제거 → A 출력
  3. setTimeout(function exec(){ console.log('B'); }, 0) 스택에 추가, 실행, 제거 비동기 함수의 실행으로 timer Web API 호출, 콜백 함수 function exec(){ console.log('B'); } 큐에 추가
  4. console.log('C') 스택에 추가, 실행, 제거 → C 출력
  5. main() 스택에서 제거 → 스택 빈 상태
  6. 큐의 콜백 함수 function exec(){ console.log('B'); } 스택에 추가, 실행, 제거 → B 출력

 

 

https://velog.io/@seokkitdo/이벤트-루프란

https://medium.com/sjk5766/javascript-비동기-핵심-event-loop-정리-422eb29231a8

https://velog.io/@thms200/Event-Loop-이벤트-루프

https://blog.toktokhan.dev/t-767eb0fa38f3

 

'자바스크립트' 카테고리의 다른 글

IIFE  (0) 2023.04.26
Rest parameter와 Spread syntax  (0) 2023.04.19
Node.js의 동작방식  (0) 2023.04.05
동기적 실행 vs 비동기적 실행  (0) 2023.03.28
프로토타입 체이닝 (상속 흉내)  (0) 2023.03.24