자바스크립트 이벤트 루프

KyungminLee·2021년 5월 12일
1
post-thumbnail

자바스크립트의 가장 큰 특징 중 하나는 단일 스레드(Single thread) 기반 언어이며, 동기적 언어 이다. 이 의미는 동시에 하나의 작업만을 처리할 수 있다라는 말이다. 하지만 실제로 자바스크립트가 사용되는 환경을 생각해보면 많은 작업이 동시에 처리되고 있는 걸 볼 수 있다. 어떻게 동시에 처리할 수 있는 걸까...

이때 등장하는 개념이 이벤트 루프(event loop) 이다.

Event loop

JS Engine

자바스크립트 엔진은 Memory HeapCall Stack 으로 구성되어 있다.
가장 유명한 것이 구글의 V8 Engine이다.
자바스크립트는 단일 스레드 (sigle thread) 프로그래밍 언어인데,
이 의미는 Call Stack이 하나 라는 의미이다.

엔진(v8) 요청이 들어올 때마다 해당 요청을 순차적으로 호출 스택에 담아 처리할 뿐이다.
그렇다면 비동기 요청은 어떻게 이루어지며, 동시성에 대한 처리는 누가 하는 걸까?
바로 이 자바스크립트 엔진을 구동하는 환경, 즉 브라우저Node.js가 담당한다.

  • Memory Heap : 메모리 할당이 일어나는 곳 (ex, 선언한 변수, 함수 등이 담겨져 있음)
  • Call Stack : 코드가 실행될 때 쌓이는 곳. stack 형태로 쌓임.

Web APIs

Web API 는 브라우저에서 제공하는 API 로, DOM, Ajax, Timeout 등이 있다.
Call Stack에서 실행된 비동기 함수는 Web API를 호출하고,
Web API는 콜백함수를 Callback Queue에 담아둔다.(promise, callback, clickevent etc..)

Callback Queue

비동기적으로 실행된 콜백함수가 보관 되는 영역.
Task Queue, Microtask Queue 등이 존재 한다.(setTimeout, promise 등 다른 큐에 추가된다)

Event loop

Event Loop는 Call Stack과 Callback Queue의 상태를 체크하여,
Call Stack이 빈 상태가 되면, Callback Queue의 첫번째 콜백을 Call Stack에 추가한다.

Event loop CallStack 처리

JS 처리과정

다음 코드를 바탕으로 자바스크립트 처리과정을 살펴보자.

console.log("script start");

setTimeout(function() {
  console.log("setTimeout");
}, 0);

Promise.resolve().then(function() {
  console.log("promise1");
}).then(function() {
  console.log("promise2");
});

console.log("script end");

위의 코드를 실행하면 다음과 같은 결과 화면을 얻을 수 있다.

script start
script end
promise1
promise2
setTimeout

Promise, setTimeout 순으로 실행되는 이유 = Microtask

마이크로 태스크는 쉽게 말해 일반 태스크보다 더 높은 우선순위를 갖는 태스크라고 할 수 있다. 즉, 태스크 큐에 대기중인 태스크가 있더라도 마이크로 태스크가 먼저 실행된다.

즉, Promise의 then()의 콜백 은 Task Queue가 아닌 Microtask Queue에 담긴다.

참고

nhn Cloud 자바스크립트와 이벤트루프

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

profile
끊임없이 발전해가는 개발자.

0개의 댓글