자바스크립트 엔진
가장 대중적인 자바스크립트의 엔진은 구글의 V8 엔진입니다. V8 엔진은 크롬과 노드 안에서 동작합니다.
자바스크립트 엔진은 다음과 같은 두 가지 주요 구성 요소로 이루어져 있습니다.
실행 환경(Runtime)
브라우저에는 자바스크립트 개발자가 사용하는 거의 모든 API가 있습니다 (ex: setTimeout ). 그러나 이런 API 들은 엔진에서 제공해주지 않습니다. 그렇다면 이 API들은 어디서 오는 걸까요?
브라우저는 단순히 엔진 하나만으로 구성되어 있지 않습니다. DOM, AJAX, setTimeout 등의 브라우저에서 제공하는 Web API라고 하는 것들이 있습니다. 또한 이러한 Web API의 호출을 통제하기 위한 Event Queue와 Event Loop도 존재합니다.
호출 스택(Call Stack)
자바스크립트는 단일 스레드 프로그래밍 언어이므로, 단일 호출 스택이 있습니다. 단일 호출 스택이 있다는 뜻은 한 번에 하나의 일(Task)만 처리할 수 있다는 뜻입니다.
호출 스택이란 프로그램에서 우리가 어디에 있는지를 기본적으로 기록하는 데이터 구조입니다. 동작 방식은 다음과 같습니다. 함수를 실행하면 해당 함수의 기록을 스택 맨 위에 추가(Push) 합니다. 우리가 함수를 결과 값을 반환하면 스택에 쌓여있던 함수는 제거(Pop) 됩니다.
단일 호출 스택의 문제점
단일 스레드에서 코드를 실행하는 것은 멀티 스레드 환경에서 발생하는 복잡한 시나리오(예: deadlocks)를 고려할 필요가 없으므로 매우 쉽습니다. 그러나 단일 스레드에서 실행하는 것도 상당히 제한적입니다. 자바스크립트에서는 하나의 호출 스택만 있기 때문에, 하나의 함수 처리가 엄청 느려서 다른 함수 실행에 지장을 줄 때는 어떻게 해야 할까요?
비동기 콜백(Asynchronous callbacks)
가장 쉬운 해결책은 비동기 콜백을 사용하는 것입니다. 즉, 우리의 코드 일부를 실행하고 나중에 실행될 콜백(함수)를 제공합니다. 비동기 콜백은 즉시가 아닌, 특수한 시점에 실행되므로 console.log와 같은 동기 함수와는 다르게 스택 안에 바로 push 될 필요가 없습니다. 그런데 스택이 아니라면 이 콜백 함수들은 누가 관리하는 걸까요?