이벤트 루프는 자바스크립트 코드가 런타임에서 어떠한 방식과 순서대로 실행이 되는지 알기 위해 꼭 알고 있어야하는 개념이다.
또, 이와 관련해서 Heap, Stack, Queue 등 기본적인 자료구조의 특성에 대한 이해 역시 필요하다.
글을 모두 읽으면 자바스크립트가 어떻게 동작하는지 순서대로 설명할 수 있을만큼의 이해를 하는 것이 목표이다.
자바스크립트의 기본 문법을 알고 더 깊이 이해하고 싶거나, 이전에 공부했지만 가물가물하다면 이 글이 적합할 것이다.
자료구조는 데이터를 구조적으로 표현한 것이다. 보통 데이터의 및 기능의 특성에 맞는 정형화된 자료구조를 사용한다. 자바스크립트의 이벤트 루프를 설명하기 위해서는 이러한 자료구조의 특성을 알고 있어야 하는데 이미 알고 있다면 이 섹션은 스킵해도 좋다.
스택은 한 방향으로 입력과 산출(Input/Output)이 이루어지는 자료구조이다. 이러한 이유로 LIFO(Last In First Out)의 특성을 가진다. 즉, 가장 최근에 쌓인 데이터가 가장 먼저 처리된다. (필자는 Queue와 헷갈릴 때 롤(LOL)의 스택을 떠올리곤 한다)
큐는 입력과 산출이 각가의 방향에서 이루어진다는 점에서 스택과 차이점이 있다. 보통 식당 대기줄에 비유하곤 하는데, 가장 먼저 기다린 사람이 가장 먼저 식당 자리에 앉을 수 있는 것처럼 말이다. 이는 큐의 중요한 특성이며, FIFO(First In First Out)으로 표현한다.
구조화 되지 않은 넓은 메모리 영역이다. 객체, 변수 등이 할당되어 실제로 저장되는 곳이다. 더 깊게 들어가면 '이진트리로 구현된 자료구조'라는 내용이 나오지만, 이벤트 루프를 위해서는 우선 이정도만 알고 있어도 될 거 같다.
[그림1] 자바스크립트 이벤트 루프 및 콜백 스택 설명const first = function(){
}
setTimeout(function(){
console.log('지연시간 0ms 타이머');
}, 0)
콜 스택은 호출된 함수를 실행하는 영역이다. 자료구조 파트에서 보았듯이 LIFO의 특성으로 가장 최근에 쌓인 함수가 먼저 실행되어 외부에 영향을 미친다.
웹 API는 본래 자바스크립트에는 없고 웹 브라우저의 외부 기능을 한다. 대표적으로 DOM 객체 접근, AJAX통신 및 setTimeout와 같은 비동기 기능 등이 있다. 런타임에서 코드를 실행하던 도중 Web API 사용이 필요한 코드를 만나면 해당 영역으로 이벤트가 위임된다. 예를 들어, setTimeout이 호출되면 이는 본래 자바스크립트에 없는 기능이기에 Web API로 옮겨지며, 지연시간이 지난 뒤 콜백 큐에 등록이 된다.
콜백 큐는 일정 시간이 지난 뒤에 처리되는 비동기 함수에서 처리한 뒤 실행시킬 함수인 콜백 함수를 저장하는 영역이다. 큐의 특성인 FIFO를 따라 가장 먼저 등록된 콜백 함수가 가장 먼저 콜 스택에 쌓이게 된다.
사실, 콜백 큐는 Web API의 특성 분류에 따라 더 세부적으로 나뉘고 우선 순위가 다르다.
마이크로 태스크 큐는 콜백 큐에서 가장 높은 우선 순위를 가진 영역이다. 그렇기 때문에 각 세부 큐에 콜백 함수가 하나씩 쌓였다고 하더라도 이벤트 루프는 마이크로 태스크 큐에 있는 콜백 함수를 가장 먼저 콜 스택에 등록한다. .then 이나 async/await 등의 비동기처리를 하는 함수는 이 큐에 담긴다.
태스크 큐는 마이크로 태스크 큐 다음으로 우선순위가 높다. setTimeout 등에 등록된 콜백 함수는 Promise .then보다 후순위, 애니메이션 이벤트보다 높은 우선 순위에서 콜 스택에 등록된다.
애니메이션 프레임은 가장 낮은 우선 순위를 가진다. 따라서 애니메이션에 관여하는 Web API는 가장 낮은 순위로 콜 스택에 등록될 것이다.
꽤나 세부적인 종류까지 알아본 콜백 큐에 다양한 콜백 함수가 쌓였다. 이벤트 루프는 계속해서 콜백 큐를 관찰하여 위에서 알아본 우선순위대로 콜백 함수를 콜백 스택에 등록한다. 이 때, 중요한 조건은 콜 스택이 비어있는지이다. 콜 스택이 비어 있는 경우에만 콜백 함수를 차례대로 등록하는 작업을 한다. 만약, 콜 스택이 비어있지 않다면, 조건을 갖출 때 까지 대기하다가 등록한다.
자바스크립트는 기본적으로 브라우저에서 실행된다. 즉, 이를 실행시키는 엔진은 브라우저가 지니고 있다. 또, 브라우저마다 사용하는 자바스크립트 엔진이 다르기 때문에 위에서 콜 스택과 Web API 중 어떤 것에 함수가 먼저 전달되는지는 상이할 수 있다. 하지만, 어떤 비동기의 우선순위가 높은지는 같기 때문에 모든 브라우저 동일한 결과를 얻을 수 있다.
지금까지 자바스크립트가 런타임에서 어떤 우선순위에서 실제로 동작하는지 알아보았다. 자바스크립트는 런타임에서 실행되는 코드의 순서를 보장하기 위해 일정한 자료구조를 이용하고 논 블로킹 방식으로 비동기를 처리한다. 이 과정에서 이벤트 루프가 비동기 처리 결과인 콜백 함수를 조건이 갖춰졌을 때 콜 스택에 등록하고 코드가 실행된다.
이벤트 루프를 설명하기 위해 자료구조의 특성에 대한 설명이 불가피했다. 최근 CS50 강의를 보면서 공부한 자료구조 지식이 도움이 되었다. 역시, 자료구조나 알고리즘 등 기본적인 컴퓨터 공학 지식의 중요성을 다시 한 번 느끼게 되었다.
참고 자료
출처
유익한 자료 감사합니다.