Open wonsss opened 2 years ago
유튜브 영상링크: 어쨌든 이벤트 루프는 무엇입니까? | Philip Roberts | JSConf EU JSConf 채널에서 Philip Roberts의 영상을 보고 요약한 내용이다.
자바스크립트가 실제로 어떻게 동작하나? 싱글 스레드 환경이라고 하나, 콜백은 실제로 어떻게 작동할까?
자바스크립트는 싱글 스레드, 논 블로킹, 비동기, 동적(single threaded, non-blocking, asynchronous, concurrent) 언어이다.
크롬에 내장된 자바스크립트 런타임인 V8 엔진은 아래와 같이 구성됐다. <자바스크립트 런타임을 단순화한 이미지>
자바스크립트는 싱글 스레드 언어로서, 싱글 스레드 런타임을 가지고 있는데, 이는 결국 한 번에 하나의 싱글 콜 스택
만을 가지고 있다는 말이다.
싱글 스레드의 의미는 하나의 프로그램은 동시에 하나의 코드만 실행할 수 있다는 것이다.
콜스택은 데이터 구조로서, 실행되는 순서를 기억하고 있다. 함수를 실행하려면, 우리는 스택에 해당하는 함수를 집어넣게 되는데, 함수에서 리턴이 일어나면 스택의 가장 위쪽에서 해당 함수를 꺼내게 된다. 이게 콜스택이 하는 일의 전부다.
블로킹은 느리게 실행되는 코드다. 예를 들어, 네트워크 요청이나 이미지 프로세싱은 느리다. 느린 동작이 스택에 남아있는 것을 보통 블로킹이라고 말한다.
동기적으로 실행되는 네트워크 요청
이 콜 스택을 블로킹
하여 브라우저가 다른 일들을 하는 것을 막고 있다.이 때문에 렌더링이나 다른 코드를 실행하지 못하고 그냥 멈춰버린다.비동기
로 만들어졌다.
일단 콜백을 받고 이것을 나중에 실행한다
는 말이다.동시성과 이벤트 루프
ajax
나 setTimeout
같은 것들과 다른 코드 실행을 동시에 할 수 있는 이유는 브라우저
가 단순한 런타임 이상을 의미하기 때문이다. Web API
같은 것들을 제공한다. Web API
같은 것들은 자바스크립트에서 호출할 수 있는 스레드를 효과적으로 지원하며, 이를 통해 자바스크립트에서도 동시성
이 가능해진다.
(setTimeout은 브라우저에서 제공하는 API이며, V8 소스코드에는 존재하지 않는다.)영상에서 구현하는 부분 캡처 및 설명
(4) 모든 WebAPI는 작동이 완료되면 콜백을 테스크 큐에 밀어넣는다. 타이머 5초가 지난 후 setTimeout함수는 작동이 완료되며, 해당 콜백을 테스크 큐에 밀어넣는다.
앞으로 큐에 쌓일 비동기식 콜백
이라고 묘사할 수 있다.드디어 이벤트 루프에 다달았다. 이벤트 루프
란 무엇일까?
큐
의 첫번째 콜백을 스택
에 쌓는 것이다.forEach 메서드, asyncForEach(커스텀함수) 작동과정 비교
렌더링
브라우저는 화면을 매 16밀리초마다, 1초에 60프레임을 repaint하는 것이 제일 빠르며 기본적이다.
하지만 브라우저는 우리가 자바스크립트로 하는 무언가로 인해 제약을 받게 된다.
즉, 스택에 코드가 쌓여 있으면, 렌더링을 진행하지 못한다. 렌더도 하나의 콜백처럼 행동하기 때문이다. 렌더링을 하려면 스택이 비워질 때까지 기다려야 한다.
렌더
와 다른 콜백의 차이점이라면 렌더
는 우리가 만든 콜백에 비해 더 높은 우선순위를 가진다는 것이다. 매 16밀리초마다 큐에 렌더가 들어가고, 스택이 깨끗해진 후에야 렌더링이 재개된다. 느린 동기식 루프를 실행하는 동안, 렌더는 막히게 된다. 렌더가 막히면, 사용자가 브라우저 화면의 텍스트를 선택하거나 선택해서 반응을 보거나 하는 것이 불가능하다.
비동기식 루프를 실행하면, asyncForEach 커스텀 함수의 setTimeout을 큐에 쌓는 동안 스택에 콜백이 쌓인다. 그러나 콜백을 큐에 일단 넣고 나서는, 큐에서 스택으로 콜백을 넘기며, 콜백이 스택에서 상대적으로 빨리 사라지고 있다. 이를 통해 과정 중간마다 렌더를 할 수 있는 기회가 주어진다.
event loop를 막는다는 것은 스택에 필요없는 느린 코드를 쌓음으로써 브라우저가 할 일을 하지 못하도록 하는 것이다. 유려한 UI(Fluid UI)를 만들기 위해 이러한 점을 고려하자.
태스크 큐
(또는 이벤트 큐, 콜백 큐)는 비동기 함수의 콜백 함수(또는 이벤트핸들러)가일시적으로 보관
되는 영역이다.프로미스의 후속 처리 메서드의 콜백 함수
가 일시적으로 보관되는마이크로태스크 큐
도 존재한다.이벤트 루프
는 콜 스택에 현재 실행 중인 실행 컨텍스트가 있는지, 그리고 태스크 큐에 대기 중인 함수(콜백함수, 이벤트핸들러 등)가 있는지 반복해서 확인한다. 만약 콜 스택이 비어 있고 태스크 큐에 대기 중인 함수가 있다면 이벤트 루프는 순차적(FIFO)으로 태스크 큐에 대기 중인 함수를 콜 스택으로 이동시키고, 콜 스택으로 이동된 함수는 실행된다.