비동기, 싱글 스레드, 콜백 큐, 호출 스택, 메모리 힙, WebAPIs, 이벤트루프 자바스크립트 개발자라면 지금 나열된 단어들에 생소하신 분들도 있겠지만 대부분 들어보셨을 겁니다.
모두 자바스크립트 동작 원리와 관련된 개념들인데요. 이 글에서 해당 개념들과 더불어
자바스크립트가 어떻게 동작하는지에 대해 알아보는 시간을 갖도록 하겠습니다.
쉽게 설명하자면 한번에 하나의 일 밖에 처리할 수 없다는 뜻입니다. 자바스크립트에서는
어떤 작업을 진행 할 때 호출 스택(Call Stack)에 쌓고 하나씩 처리합니다.
호출 스택(Call Stack)이란 자료구조의 한 형식입니다.
한 가지 예시를 들어보겠습니다
앞에 아래는 막히고 위에는 뚫려있는 빈 병이 하나 있습니다. 이 빈병에 동전을 다섯개를 집어 넣고 다시 빼봅시다. 그러면 늦게 들어간 동전이 제일 먼저 나오고 처음 들어간 동전이 가장 마지막에 나올겁니다. 이렇듯 스택은 선입후출 방식으로 된 자료구조를 일컫는 용어입니다.
자바스크립트에서 호출 스택으로 어떻게 작업을 진행하는지 아래의 코드를 살펴보며
이해해봅시다.
function plus (x, y) {
return x + y;
}
function printCalc() {
var result = plus(5, 10);
console.log(result);
}
printCalc();
위의 코드를 실행 과정을 스택 프레임(Stack Frame)을 이용하여 단계별로 설명하면
아래의 그림과 같습니다.
이처럼 호출 스택은 위에서 아래로 인터프리터하면서 만나는 작업을 순차적으로 처리하는
동기적 특성을 갖습니다. 그럼 만약 처리시간이 어마어마하게 오래 걸리는 함수가 있다면
해당 함수가 실행되는 동안 브라우저는 아무것도 못하고 대기 상태가 될 것 입니다.
그렇게 흰 화면만 나오다가 머지않아 아래와 같은 그림을 마주하게 될지도 모릅니다.
이 문제를 해결하기 위한 해결책은 바로 비동기 콜백입니다. 여러분이 잘 아시는
setTimeout와 같은 함수가 비동기 콜백을 가능하게 해줍니다.
이제 자바스크립트 런타임 과정을 설명하며 어떻게 비동기 처리하는지 살펴보겠습니다.
브라우저는 독자적인 자바스크립트 엔진을 가지고 있습니다. 대표적인 예는 Chrome과 Node.js에서 사용되고 있는 구글의 V8엔진입니다.
아래의 그림은 엔진의 구조도입니다.
Memory Heap : 메모리 할당이 이루어지는 곳
Call Stack : 코드 실행에 따라 호출 스택이 쌓이는 곳
비동기 콜백을 설명하려면 자바스크립트 엔진뿐만 아니라 다른 요소들도 필요합니다.
아래의 그림을 보시죠.
자바스크립트 엔진뿐만 아니라 WebAPIs, 콜백 큐, 이벤트 루프라는 요소가 보입니다. 이들은
모두 브라우저에서 제공하는 요소들입니다.
console.log("My name is");
setTimeout(function(){
console.log("JavaScript!");
}, 1000);
위의 코드를 실행하면 어떻게 처리되는지 알아보도록 하겠습니다.
2. setTimeout는 비동기 함수이므로 webAPIs로 이동합니다. 이곳에서 설정한 1초가 지나면
콜백 큐로 이동합니다. 그동안 console.log()는 실행되어 호출 스택에서 지워집니다.
3. 콜백 큐로 이동한 setTimeout은 이벤트 루프가 호출 스택이 비어있는지를 확인하고, 보내어
실행합니다.
이벤트 루프는 호출 스택이 비어있는지를 주기적으로 확인하고 비어있으면 콜백 큐에 쌓인 작업들을
순차적으로 호출 스택으로 보내는 역할을 합니다.