TIL/JavaScript

[ECMAScript6+를 위한 보충학습] 1. EventLoop

Art Rudy
반응형

EventLoop

개요

자바스크립트는 기본적으로 단일쓰레드에서 동작한다. 하지만 주로 웹에 쓰이는 언어다보니, 단일쓰레드에서 동기적으로만 동작한다면 이런저런 문제가 발생할 수 있다. 외부에서 용량이 큰 데이터를 받아서 띄워주는 경우를 예로 들어보자. 만약 데이터를 받는 시간이 밀리세컨드 단위라면 동기적으로 실행되어도 큰 문제는 없을 것이다. 하지만 받는 시간이, 1, 2초나 그 이상의 시간이 걸리는 경우, 최악의 경우엔 데이터 파일 하나 때문에 웹페이지 전체를 띄우지 못하는 경우가 생길 수 있다. 이러한 문제 상황에 대비해서, 자바스크립트에서는 단일쓰레드에서도 비동기적인 프로그래밍이 가능하도록 몇 가지 장치를 해두었는데, 그것이 Event Queue Event Loop이다.

 

Call Stack

Call Stack은 비단 자바스크립트가 아니더라도 대부분의 언어에 존재하는 개념이다.

 

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

 

함수가 시작되면 CallStack에 해당 함수가 쌓인다. 이 때 쌓이는 구조는, 자료구조의 스택과 동일하다. 만약 함수가 종료되면 해당 함수는 CallStack에서 제거된다. 함수가 종료되기 전에 또 다른 함수가 실행되면, 해당 함수는 종료되지 않은 기존 함수 스택 위에 새로운 스택으로서 쌓이게 된다. 동기적인 프로그램만 구현한다고 가정한다면, 아래 요소들 없이 CallStack만으로도 충분히 원하는 프로그램을 작성할 수 있다. 하지만 비동기적인 프로그램을 구현한다고 한다면, 콜 스택과는 다른 공간에서 동작하는 무언가가 필요할 것이다.

 

Event Queue & Event Loop

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

 

자바스크립트의 Event Queue Event Loop는 이러한 상황을 해결할 수 있게 해준다. 일반적으로 자바스크립트에서 "콜백함수"로 실행된 함수들은 실행과 함께 별도의 WebApi로 보내져서 동작한다. 그리고 동작이 끝나면 Event Loop EventQueue에 에 있는 함수들을 차례로 실행시킨다. Mdn에서는 Event Queue에 대한 동작을 위와 같이 정의하고 있다.

 

while(queue.waitForMessage()) {
    queue.processNextMessage();
}

 

이 때, queue.waitForMessage() 함수는 현재 아무 메시지도 없다면 새로운 메시지 도착을 동기적으로 기다린다. 만약, 대기열에 메세지가 없는데 새로운 메세지가 들어왔다면, 곧바로 해당 메세지가 실행된다. 하지만 기존에 다른 메세지가 기존에 존재한다면, 먼저 있던 메세지들의 동작이 다 끝나야 다음 메세지가 동작할 수 있다. 이러한 동작은 다음과 같은 결과에서 다시 확인할 수 있다.

 

Zero Delay

setTimeout(funcA, 0);

 

setTimeout 함수는 대기 시간이 0이다. 이것만 보면 마치 0초 뒤에 바로 함수가 실행되어야 할 것 같지만 그렇지 않다. 다음 두 가지 이유 때문이다.

 

  1. 콜스택에 이미 다른 함수가 쌓여 있다.
  2. Event Queue에 먼저 온 메세지가 쌓여 있다.

 

다음 두 가지 경우에 자바스크립트는 쌓여 있는 콜스택을 최우선으로 처리하고, 이후 먼저 온 메세지를 처리한다. , setTimeout에서 정의한 시간은 최소지연시간을 나타낼 뿐, 정확한 동작 시간을 보장하지는 않는다는 것이다.

반응형

'TIL > JavaScript' 카테고리의 다른 글

[ECMASciprt6+ Features] 5. Arrow Functions  (0) 2021.07.22
[ECMASciprt6+ Features] 4. let & const  (0) 2021.07.22
[ECMASciprt6+ Features] 3. Class  (0) 2021.07.21
[ECMAScript6+를 위한 보충학습] 2. Callback  (0) 2021.07.21
ECMAScript6+  (0) 2021.07.21