자바스크립트는 싱글 스레드 언어이기 때문에 한 번에 하나의 동작만 수행할 수 있다. 오직 하나의 실행 컨텍스트 스택만 존재하며, 오직 스택의 최상단의 컨텍스트만 실행할 수 있다. (동시에 스택의 최상단 컨텍스트는 지금 실행 중인 컨텍스트를 의미하기도 한다)
자바스크립트의 '스택' 자료구조인 실행 컨텍스트
하지만 브라우저가 동작하는 것을 보면 많은 일을 동시에 처리되는 것처럼 느껴진다. HTTP 요청을 통해 서버로부터 데이터를 가지고 오면서 동시에 렌더링하는 비동기 통신이 대표적인 예시이다.
예시로 유튜브 동영상 하나를 클릭해본다. 페이지에 들어가게 되면 동영상을 로딩하는 동시에 댓글도 로딩이 되며 옆에는 연관 동영상 리스트가 로딩된다. 어떻게 하나의 동작만 수행할 수 있는 자바스크립트에서 이런 일이 일어날 수 있을까?
동시에 여러 태스크가 처리되는 것처럼 느끼는 것을 가능하게 해주는 것이 바로 이벤트 루프 이다.
자바스크립트 엔진의 대표적인 구조
비동기 처리에서 소스코드의 평가와 실행을 제외한 모든 처리는 자바스크립트 엔진을 구동하는 환경인 브라우저 또는 Node.js가 담당한다.
브라우저 환경에서는 콜백 큐(Callback queue)를 제공하는데, 콜백 큐란 setTimeout
,setInterval
을 포함한 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이다.
이벤트 루프는 콜 스택에 현재 실행 중인 실행 컨텍스트가 있는지, 그리고 태스크 큐에 대기중인 함수(콜백 함수, 이벤트 핸들러 등)가 있는지 반복해서 확인하며 태스크 큐에 대기 중인 함수를 실행 컨텍스트로 옮기는 것을 의미한다.
만약 콜 스택이 비어 있고 태스크 큐에 대기 중인 함수가 있다면 이벤트 루프는 순차적 (FIFO)으로 태스크 큐에 대기 중인 함수를 콜 스택으로 이동시킨다.
이때 스택으로 이동한 함수는 바로 실행되며 태스크 큐에 일시 보관된 함수들은 콜 스택이 빌 때까지 대기한다.
자바스크립트는 싱글 스레드 방식으로 동작한다.
하지만 브라우저에서 싱글 스레드 방식으로 동작하는 것은 브라우저가 아닌 브라우저에 내장된 자바스크립트 엔진이다. 즉, 브라우저에 내장 된 자바스크립트 엔진은 여전히 싱글 스레드로 동작하지만 브라우저는 멀티 스레드로 동작한다.
끝으로 이벤트 루프를 이해할 때 좋은 영상이다. 이해가 쉽지 않다면 영상을 참고해도 좋을 것 같다.