[Javascript] 이벤트 루프와 비동기

TaeHyeon·2020년 1월 30일
0
post-thumbnail

자바스크립트에서 비동기 프로그래밍이 필요한 이유

만약 자바스크립트가 동기적으로 작동된다면 어떻게 될까? 예를 들어 서버에서 사용자의 정보를 받아오는 함수가 있다고하자, 그럼 브라우저는 서버에서 정보를 받아올때까지 다른 함수를 실행할 수 없다. 이때 프로그램은 정보를 다받아올때까지 아무것도 하지 못하는 상태가 된다. 이렇게 된다면 사용자 경험은 최악이 될것이다.

자바스크립트는 싱글 스레드 언어이기 때문에 한번에 한가지 일만 할 수 있다. 하지만 자바스크립트를 경험해본 개발자라면 그렇지 않다는 것을 알고있다. 대표적인 비동기 함수로 setTimeout 함수가 있다.

console.log(1);
setTimeout(() => {
  console.log(2);
}, 1000)
console.log(3);
//1
//3
//2

1이 출력된 후 자바스크립트는 setTimeout를 실행하고 바로 다음 코드로 넘어가 코드를 실행한다. 그리고 1초후 setTimeout의 인자로 들어간 함수가 실행된다. 싱글 스레드 언어인 자바스크립트에서 어떻게 이런일이 가능할까?

V8 Engine

브라우저는 자바스크립트가 실행되는 환경이고 V8 Engine은 크롬 브라우저에서 자바스크립트를 실행 할때 내부적으로 사용되는 엔진이다. 이 엔진이 자바스크립트가 동시에 여러가지 일을 할 수 있게 해준다. V8 Engine은 다시 여러개의 요소로 이루어져있다.

V8 Engine

힙(Heap)

힙은 변수 혹은 객체에 대한 메모리 할당이 일어나는 곳이다.

스택(Stack)

자바스크립트 프로그램이 저장되는 곳이다. 함수가 실행되면 스택에 쌓이게되고 함수가 종료되면 스택에서 빠져나온다.

Web APIs

Document, AJAX, Event, Timing 등 코어 자바스크립트에 없는 기능을 지원한다. 브라우저에서 지원하는 기능들이다. 대표적으로 setTimeout이 있다.

Callback Queue

setTimeout같은 비동기 함수가 실행됐을 경우에 일정시간이 지난후 실행되는 함수를 대기 시키는 곳이다.

Event loof

Callback Queue에서 대기하고있는 함수를 스택이 비면에 스택으로 함수를 넣는다.

자바스크립트에서의 비동기 흐름

function one() {
  console.log(1);
}

function two() {
  console.log(2);
}

function three() {
  console.log(3);
}

one();
setTimeout(two, 1000);
three();
//1
//3
//2

출력되는 값은 1,3,2 순서가 된다. 이 코드를 자세히 살펴보면

  1. 스택에 one() 함수가 들어가고 바로 실행되고 빠져나온다.
  2. setTimout 함수가 실행되고 setTimout 함수안에 있던 two() 함수가 Web API로가서 1초동안 대기한다.
  3. 스택에 three() 함수가 들어가고 바로 실행되고 빠져나온다.
  4. Web API에서 대기하고있던 함수가 1초가 지난 후 Callback Queue로 이동하고 대기한다.
  5. Event loof는 Callback Queue에서 대기하고 있는 함수를 스택이 비어있으면 스택에 함수를 넣는다.
  6. 1초 후 two함수가 스택으로 이동하고 스택에서 함수가 실행되고 프로그램이 종료된다.

setTimeout

이벤트루프는 Callback Queue에서 대기중인 함수를 스택으로 넣어주는 역할을 하는데 만약 스택에 함수가 남아있을 경우 스택이 비워질때 까지 기다린후 함수를 넣어주게 된다.

따라서 setTimeout은 정확한 지연시간을 보장해 주지 않는다.

0개의 댓글