본문 바로가기

JavaScript

[요약] What the heck is the event loop anyway? 이벤트 루프란 무엇인가?

반응형

세줄요약

event loop는 callstack과 task queue를 주시하며
callstack이 비어있다면 task queue의 가장 오래된(첫번째) 메세지를
callstack에 넣어주어서 메세지(콜백함수)가 실행되게 하는 것.

 

event loop에 관하여 깊게 이해하고 싶어서

코드스테이츠에서 제공했었던 동영상을 중심으로 핵심을 뽑아보았다.

 

https://www.youtube.com/watch?v=8aGhZQkoFbQ 

 

자바스크립트는? 

 

싱글 스레드 non-blocking 비동기 동적 언어

(a single-thread non-blocking asynchronous concurrent language)

- 콜스택

- 이벤트 루프

- 콜백 큐

- other APIs and stuff

 

V8 에는 콜스택, 이벤트 루프, 콜백 큐, other APIs and stuff가 있는가?

 

콜스택과 힙만 있다.

 

크롬의 V8 자바스크립트 런타임

자바스크립트 런타임을 단순화 한 것

자바스크립트 런타임에서는(v8) 메모리 할당이 일어나는 힙과 콜 스택을 확인할 수 있다.

 

런타임(v8)에서는 비동기 코딩에서 가장 먼저 생각하는 것들인 setTimeout, DOM, AJAX Request 은 없었다.

런타임 + webAPI

자바스크립트는 어떻게 작동할까?

 

자바스크립트는 싱글 스레드 프로그래밍 언어.

 

하나의 프로그램은 동시에 하나의 코드만 실행할 수 있다는 것

 

블로킹이란?

 

느리게 동작하는 코드(네트워크 요청, 이미지 프로세싱)가 스택에 남아있어서

 

다음 동작이 일어나지 못하게 하는 것을 블로킹이라고 한다.  


프로그래밍 언어에서 싱글 스레드라는 것은 느리게 동작하는 코드가 있어도 이 결과가 나올때까지 기다리는 것. 

 

왜 이것이 문제일까? 코드가 브라우저에서 실행되기 때문이다.

 

느리게 동작하는 코드가 실행 중에는 다른 아무것도 클릭을 할 수 없다. (브라우저가 멈췄다.)

 

콜스택에 느리게 동작하는 코드가 남아 있으면(실행중이면) 콜 스택을 블로킹하여 브라우저는 다른 일을들 할 수 없다.

 

해결 방법은 비동기 콜백!

 

setTimeout method를 사용하여 비동기를 구현하는 경우에 

 

setTimeout은 콜스택에 들어왔다가 금방 사라지고

 

다음 함수가 콜스택에 들어온다. 그리고...

 

setTimeout의 두번째 dependency 즉 지정한 시간 이후에 콜백함수를 실행된다.

 

나중에 콜백함수를 실행하기 위해서는 이벤트 루프와 동시성이 역할을 하게 되는데...

 

그럼 javascript가 한번에 한가지 일을 한다는 것은 거짓말인가? Nope.

 

이것이 가능한 것은 브라우저가 단순한 런타임(실행환경) 이상이기 떄문.

 

브라우저는 web API(setTimeout)를 제공한다.

그리고 이 web API는 자바스크립트에서 호출할 수 있는 스레드를 효과적으로 지원하는데 여기서 동시성이 온다.

 

즉 setTimeout은 브라우저에서 제공하는 API이다. Javascript가 실행되는 런타임 환경에 존재하는 별도의 API로 setTimeout이 콜스택에 왔다가 사라지는 것은 setTimeout 호출자체는 완료되었다는 것이고(처리는 브라우저에 한다는 것을 의미),

브라우저에서 타이머를 실행시키고 카운트 다운을 하기 때문임.

 

javascript는 single thread이기 때문에 webAPI가 갑자기 작성된 코드에 끼어들 수 없다.

 

이를 위해서 task queue가 필요한데

 

WebAPI 작동이 완료되면  콜백함수를 task queue에 넣어준다. 

 

task queue에 들어있는 콜백함수를 callstack에 넘기기 위해 필요한 것이 바로 event loop인데

 

즉 event loop는 callstack과 task queue를 주시하며

call stack이 비어있다면 task queue의 첫번째 콜백함수를 스택에 쌓아주어 콜백함수가 실행되게 하는 것.

 

setTimeout(cb, 0)의 의미는?

 

스택이 비어있을때 까지 기다리는 것을 의미.

 

setTimeout, AJAX Request 같은 Web API는 동일한 방식으로 동작한다. 

 

AJAX Request는 URL로 호출할 때 콜백을 함께 실행하게 되는데,

 

AJAX Request는 Javascript runtime이 아니라 브라우저 Web API에서 실행된다. 

 

XHR webAPI가 실행되는 동안 다른 코드는 정상적으로 실행되며 XHR 실행이 완료되었다면

콜백은 task queue에 쌓이게 되고, 이벤트루프에 의해 callstack에 쌓여서 실행된다.

 

XHR(XMLHttpRequest)은 AJAX 요청을 생성하는 webAPI이고, XHR의 메서드로 브라우저와 서버간의
네트워크 요청을 전송할 수 있다.
AJAX(Asynchronous JavaScript And XML)는 특정 기술이 아니라 HTML, CSS, JavaScript, DOM조작, XHR object를 활용한 프로그래밍 방식이다. AJAX는 전체 페이지가 다시 로드되지 않고 일부분만 업데이트하는 좀 더 복잡한 웹페이지를 만들 수 있게 해준다. 덕분에 어플리케이션은 보다 빨라지고, 사용자 행동에 대한 반응성도 좋진다. 

 

브라우저는 기본적으로 화면을 매 16.6ms, 즉 1초에 60프레임을 repaint(render)한다.


하지만 브라우저는 자바스크립트로 하는 것들로 인해 여러가지 이유로 제약을 받는다.

 

그래서 콜스택에 코드가 있으면 렌더링을 못한다.

 

왜냐하면 render(repaint)도 하나의 콜백처럼 행동하기 때문에 스택이 비워질 때까지 기다려야 하는 것이다.

 

하지만 다른점이라면 render는 다른 콜백함수보다 더 높은 우선순위가 있으므로 매 16ms마다 큐에 렌더가 들어가고,

 

스택이 깨끗해진 후에야 렌더를 한다.

 

따라서 우리는 스택에 필요없는 느린 코드를 쌓아서 브라우저가 할일(유동적인 UI를 목표로)을 못하게 만들지 말아야한다. 렌더에게 각 요소 중간중간에 렌더가 끼어들 수 있는 기회를 주어야 한다. 

반응형