이벤트 루프

박정훈·2022년 1월 25일
0

Java Script

목록 보기
5/8

자바스크립트는 single thread, 단일 스레드 기반의 언어다. 단일 스레드라면 당연하게도 동시에 하나의 작업밖에는 처리하지 못한다는 것을 의미한다. 그렇지만 당장 웹만 봐도 동시에 많은 작업이 처리되고 있다. 어떻게 자바스크립트는 스레드 하나 가지고, 이와 같은 동시성(Concurrency)을 지원할까? 여기서 이벤트 루프가 튀어나온다. 자바스크립트는 이벤트 루프를 이용해서 비동기 방식으로 동시성을 지원한다.

이벤트 루프

자바스크립트 엔진 V8은 단일 호출 스택을 사용하고, 요청이 들어올 때마다 순차적으로 해당 요청을 호출 스택에 담아 처리한다. 역시 하나씩 처리한다. 그렇다면 비동기 요청과 동시성에 대한 처리는? 자바스크립트 엔진을 구동하는 환경인 브라우저나 Node.js가 담당하는 것이다.

브라우저

비동기 호출을 위해 사용하는 브라우저의 Web APIs

Node.js

Node.js는 비동기 작업을 위해 libuv 사용, libuv가 이벤트 루프를 제공한다.
단일 호출 스택을 사용하는 js 엔진이 브라우저나 Node.js와 상호 연동하기 위해 사용되는 녀석이 이벤트 루프다.

자바스크립트 엔진은 하나의 호출 스택을 사용하며, 현재 스택에 쌓여있는 모든 함수들이 스택에서 pop 되기 전까지는 다른 어떠한 함수도 실행될 수 없다.

function delay() {
  for (let i = 0; i < 100000; i++);
}

function youHavetoWait() {
  delay();
  waitMore();
  console.log("done~~");
}

function waitMore() {
  delay();
  console.log("wait please~~");
}

function timeoutFunc() {
  console.log("call setTimeFunc");
}
setTimeout(timeoutFunc, 0);
youHavetoWait();

// wait please~~
// done~~
// call setTimeFunc
  1. setTimout 함수는 브라우저에게 타이머 이벤트를 요청한 후 바로 스택에서 제거 된다.
  2. youHavetoWait 함수가 스택에 올라온다.
  3. for문이 열심히 돌아가고, waitMore 함수를 스택에 올린다.
  4. waitMore함수가 제거되고, youHavetoWait 까지 제거 되면 timeoutFunc 의 console이 출력된다.

여기서 알 수 있는 점은 자바스크립트의 타이머는 정확한 시간을 보장해주지 않는다는 것이다. 0을 줬다고 해도 바로 실행하지 않는다. 스택을 모두 비워야만 올라간다. 실제로도 0이 즉시를 의미하지도 않는다. 브라우저 내부적으로 타이머의 최소단위를 정해놓고 있기 때문이다.

여기서 setTimeout의 콜백이 바로 이벤트 루프에 의해서 실행된다. 이벤트 루프는 콜 스택을 관찰하고 있다가, 콜 스택이 비워진 것을 확인하고 task queue에 올라온 콜백 함수를 스택에 올린 것이다.

태스크 큐

모든 비동기 API 작업들의 콜백 함수는 태스크 큐에 추가된다. 이렇게 모인 콜백 함수들이 대기하는 큐 형태의 배열이며, 이벤트 루프는 현재 실행중인 태스크가 없다면 태스큐 큐의 첫 번째 태스크를 꺼내서 콜 스택에 올린다.

마이크로 태스크 큐

Proimise 또한 비동기로 실행된다고 볼 수 있다. 다만 이 친구의 콜백 함수들은 마이크로 태스크 큐로 간다. 우선순위가 태스크 큐보다 높기 때문에 먼저 실행된다. 이벤트 루프는 태스크 큐에서 하나만을 처리하고 다시 갈길을 가는 반면에 마이크로 태스크 큐는 완전히 비워질 때까지, 중간에 계속 올라와도 모두 처리해야만 떠난다.
추가로 MutationObserver(DOM의 변화를 감지한다.)의 콜백 함수들도 마이크로 태스크 큐로 들어간다.

리퀘스트 애니메이션 프레임

렌더는 브라우저에서 특정 요소가 움직이거나, 애니메이션을 할 때 주기적으로 호출되는데, requestAnimationFrame 함수를 통해 콜백 함수를 등록 해 놓으면, Request Animation Frame queue에 콜백이 쌓이고, 다음번 브라우저 업데이트 때 이벤트 루프는 Request Animation Frame queue에 쌓인 콜백 함수들을 콜 스택에 올린다.

profile
그냥 개인적으로 공부한 글들에 불과

0개의 댓글