[JS] 자바스크립트 동작 원리(콜 스택, 콜백 큐, 이벤트 루프)

daybyday·2020년 12월 28일
11

Javascript

목록 보기
9/15
post-thumbnail
post-custom-banner

자바스크립트는 단일 스레드 기반

자바스크립트는 단일 스레드, 동시에 하나의 작업만을 처리할 수 있다고 한다. 그러나 여러 작업이 동시에 처리되는 것 같은데 어떻게 동시성을 지원하는 걸까?

자바스크립트 엔진 V8의 구조는 위와 같다.

  • Memory Heap: 메모리 할당이 일어나는 곳
  • Call stack: 코드 실행에 따라 스택 프레임이 쌓이는 곳(LIFO 후입 선출)

호출 스택이 하나이므로 자바스크립트가 단일 스레드인 것은 맞다.

자바스크립트 런타임(동작 환경)

그러나 자바스크립트 엔진을 '구동하는 환경', 즉 브라우저나 Node.js에서는 여러 개의 스레드가 사용된다.

  • Web APIs : DOM, AJAX, Timer 등 브라우저에서 제공하는 api
  • Callback queue : 콜백 함수들이 대기하는 곳(FIFO 선입선출)
  • Event Loop : call stack이 비워질 때마다 callback queue에 대기 중인 콜백함수가 있다면, callback 함수를 call stack에 보내줌.

이러한 구동환경에서 자바스크립트 엔진과 상호 연동하기 위해 사용하는 장치가 Event loop이다.

호출 스택 (Call stack)

호출 스택은 여러 함수들(functions)을 호출하는 스크립트에서 해당 위치를 추적하는 인터프리터 (웹 브라우저의 자바스크립트 인터프리터같은)를 위한 메커니즘입니다. 현재 어떤 함수가 동작하고있는 지, 그 함수 내에서 어떤 함수가 동작하는 지, 다음에 어떤 함수가 호출되어야하는 지 등을 제어합니다.
- MDN


function multiply(x, y) {
    return x * y;
}
function printSquare(x) {
    var s = multiply(x, x);
    console.log(s);
}
printSquare(5);

위와 같은 코드가 실행될 때 호출 스택의 동작 단계는 다음과 같다.

function foo {
  foo();
}
foo();

위와 같이 계속 foo()를 호출하는 함수를 만나면 콜 스택에 스택 프레임이 계속 쌓여 스택 날려버리기가 일어난다.

이벤트 루프(Event Loop)

싱글 스레드의 한계를 보완하기 위해 비동기 콜백(asynchronous callback)을 이용한다.

비동기 콜백에는 Web APIs, ES6의 Promise가 있다.

자바스크립트 코드 실행 중에 이벤트를 만나면 이벤트가 콜백 큐에 차례대로 쌓인다. 콜백 큐는 FIFO 선입선출 룰을 따른다.

이벤트 루프는 콜 스택이 비었는지 확인하고, 비었으면 콜백 큐에 있는 이벤트를 가져다 콜 스택에 밀어넣는다. 이 한 번의 작업을 틱(tick) 이라고 한다. 이벤트 루프는 이 작업은 반복(loop)한다.



아래 동영상이 자바스크립트 동작 원리를 이해하는데 많은 도움이 되었다!(한글자막 있음)

참고

https://joshua1988.github.io/web-development/translation/javascript/how-js-works-inside-engine/

https://haileychoi15.medium.com/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%98%EB%82%98%EC%9A%94-f3d07a529e41

https://developer.mozilla.org/ko/docs/Glossary/Call_stack

https://haileychoi15.medium.com/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%98%EB%82%98%EC%9A%94-f3d07a529e41


공부한 내용을 정리한 포스트입니다.
잘못된 내용이 있다면 댓글 부탁드립니다:)

post-custom-banner

0개의 댓글