자바스크립트는 싱글 스레드 언어다. 싱글 스레드란 한 번에 하나의 작업만 수행할 수 있다는 의미다. 그러나 네트워크 요청이나 타이머와 같은 작업을 멀티로 처리해야 하는 경우가 많다. 싱글 스레드로 브라우저가 한 번에 하나의 동작을 수행하게 되면, 파일을 다운로드 받는 동안 웹서핑도 못하고 대기해야 한다.
자바스크립트 엔진은 자바스크립트 코드를 실행하는 프로그램이다. 여러 목적으로 자바스크립트 엔진을 사용하지만, 주로 웹 브라우저에서 사용된다.
엔진의 기본 동작 원리
1. 엔진이 스크립트를 읽는다. (=파싱)
2. 스크립트를 기계어로 전환한다. (=컴파일)
3. 기계어로 전환한 코드를 실행한다.
V8은 웹 브라우저를 만드는 데 기반을 제공하는 오픈소스 자바스크립트 엔진이다. 구글 크롬 브라우저와 안드로이드 브라우저에 탑재되어 있다.
엔진의 주요 구성요소는 다음과 같다.
1. Memory Heap : 메모리 할당이 일어나는 곳
2. Call Stack : 코드 실행에 따라 호출 스택이 쌓이는 곳
그렇다면 setTimeout()
과 같은 내장 api는 어디에 위치하는 걸까?
위의 그림처럼 자바스크립트 엔진 외에도 자바스크립트에 관여하는 다른 요소들이 존재한다. setTimeout()
, Ajax
와 같은 api들은 Web API로, 엔진 밖에 별도로 저장된다.
이제 남은 요소들을 알아보자.
콜 스택은 프로그램에서 현재 실행 중인 서브루틴에 관한 정보를 저장하는 스택 자료구조다. 자바스크립트는 싱글 스레드 기반 언어이기 때문에 콜 스택이 하나다.
콜 스택을 사용하는 주요 목적은 현재 실행 중인 서브루틴의 실행이 끝났을 때, 제어를 반환할 지점을 보관하기 위함이다.
const asyncFunc = () => {
setTimeout(() => {
console.log('second');
}, 5000);
};
const foo = () => {
console.log('first');
};
const bar = () => {
console.log('third');
};
foo();
asyncFunc();
bar();
위의 코드를 그림으로 표현해보자. 비동기 함수인 setTimeout()
은 Web API로 이동하여 일정 시간을 대기한다. 시간이 만료되면 Callback Queue로 이동하였다가 Event Loop에 의해 실행된다.
콜백 큐는 비동기적인 작업이 끝난 함수들이 대기하는 공간이다. 콜백 큐는 세부적으로 task queue와 microtask queue로 나뉜다.
setTimeout()
, setInterval()
, fetch()
등 비동기로 처리되는 함수들의 콜백 함수가 들어간다.promise.then
, process.nextTick
등 우선순위가 높은 함수들의 콜백 함수가 들어간다.자바스크립트는 호출 스택이 하나인 싱글 스레드 언어이기 때문에 병렬성이 아닌 동시성을 지원한다.
참고자료
wikipedia : 자바스크립트 엔진
wikipedia : 콜 스택
자바스크립트의 동작 원리
Concurrency vs Parallelism