JS_12. 이벤트 루프

Seoyong Lee·2021년 5월 20일
0

JavaScript / TypeScript

목록 보기
13/25
post-thumbnail

이벤트 루프란 무엇인가?

자바스크립트는 '싱글-스레드(single-thread)'로 한 번에 한 가지 작업만을 처리할 수 있다고 알려져있다. 그러나 이러한 자바스크립트에서 비동기 처리를 할 수 있도록 해주는 것이 있으니 이것이 바로 이벤트 루프(event loop)이다.

JavaScript has a concurrency model based on an event loop, which is responsible for executing the code, collecting and processing events, and executing queued sub-tasks.

자바스크립트는 코드의 실행과 이벤트 수집 및 처리, 그리고 큐의 하위 태스크 실행을 담당하는 이벤트 루프를 기반으로 한 동시성 모델을 가지고 있다.

MDN - Concurrency model and the event loop

이벤트 루프는 말 그대로 무한히 반복되며 새로운 작업을 찾는 과정이다. 이러한 반복의 한 이터레이션을 '틱(tick)'이라고 부르며, 틱을 통해 실행되는 코드를 '태스크(task)' 라고 한다. 이러한 태스크는 '비동기적' 코드 조각들로 루프 안에 다른 태스크를 스케줄 할 수도 있으며, setTimeout이나 DOM, 유저 이벤트 등으로 만들어진다.

출처 Writing a JavaScript framework - Execution timing, beyond setTimeout

태스크는 다시 태스크 큐(task queue)를 통해 관리되는데, 태스크 큐는 여러개의 큐들로 구성된다. 이러한 태스크 큐 중에서도 가장 먼저 실행되는 하나의 마이크로 태스크 큐(microtask queue)가 존재하며, 비동기를 위한 Promise.resolve().then(microtaskFn)이 이러한 마이크로 태스크 큐를 설정하는 대표적인 객체이다. 마이크로 태스크 큐는 매 틱의 종료와 함께 비워진다.

이벤트 루프의 동작 과정

이벤트 루프가 동작하는 순서는 다음과 같다.

  1. 콜 스택(call stack)과 태스크 큐(task queue)를 번갈아가며 감시한다.
  2. 콜 스택의 작업을 처리한다.
  3. 콜 스택이 비는 순간 microtask queue를 먼저 확인하여 처리할 작업이 있다면 콜 스택으로 옮긴다.
  4. 처리할 작업이 없다면 Animation Frames를 확인한다.
  5. 모든 작업이 완료되면 태스크 큐를 확인하고 태스크 큐의 작업을 콜 스택으로 옮긴다.

출처 Writing a JavaScript framework - Execution timing, beyond setTimeout

자바스크립트 엔진과 이벤트 루프

그렇다면 이러한 이벤트 루프는 어디에 존재하는 것일까?

먼저 자바스크립트 엔진에 대해서 살펴보자. 자바스크립트 엔진은 다음과 같은 단계를 거치며 작동한다.

  1. 정보를 특정한 곳에 저장한다(Memory allocation).
  2. 현재 실행되고 있는 코드를 트래킹한다.

이러한 단계에 따라 엔진의 구성도 크게 다음과 같이 나눌 수 있다.

  1. 메모리 힙(Memory Heap): 정보 저장의 공간
  2. 콜 스택(Call stack): 실행 중인 코드의 스택

출처How JavaScript works: an overview of the engine, the runtime, and the call stack

우리가 자바스크립트에서 특정 코드를 실행시키면 코드는 일반적으로 콜 스택에 하나씩 쌓이며 동기적으로 처리된다. 그러나 특정 코드가 비동기적 처리를 필요로 한다면 이러한 코드는 바로 콜 스택에 쌓이는 것이 아닌, 엔진 밖의 API에 작업을 요청한다. 요청이 완료되면 코드는 태스크 큐에서 순서대로 실행을 대기하게되며, 이러한 코드들의 전반적인 스케줄을 관리해주는 것이 바로 이벤트 루프이다.

출처 자바스크립트 비동기 처리 과정과 RxJS Scheduler

위에서 본 것과 같이 이벤트 루프는 자바스크립트 엔진 내부에 존재하지 않으며 ECMAScript에서도 언급되어있지 않다. 그렇다면 우리는 어떻게 지금까지 이벤트 루프를 통해 비동기 처리를 할 수 있었을까? 바로 브라우저와 같은 실행환경(런타임)에서 이를 지원하기 때문에 가능했던 것이다.

참고
Philip Roberts - What the heck is the event loop anyway?
자바스크립트 비동기 처리 과정과 RxJS Scheduler
How JavaScript works: an overview of the engine, the runtime, and the call stack
Writing a JavaScript framework - Execution timing, beyond setTimeout

profile
코드를 디자인하다

0개의 댓글