이시안 개발 블로그

Call Stack & Event Loop 본문

🌐Web/Javascript

Call Stack & Event Loop

ICAN 2022. 3. 6. 23:49

 

오늘은 자바스크립트 호출 스택(Call Stack)과 이벤트 루프(Event Loop)에 공부해보겠습니다.

 

 

Call Stack

자바스크립트는 단일 스레드 기반의 언어입니다. 단일 스레드이므로 호출 스택(Call Stack)이 하나만 존재하고 이것은 한 번에 하나의 작업만 처리할 수 있다는 것을 뜻합니다.

 

Call Stack

스택은 LIFO(후입선출) 구조이며 위에서부터 차곡차곡 쌓이는 형태의 자료구조입니다. 자바스크립트는 현재 어떤 함수가 동작하고 또 다음 호출될 함수는 무엇인지 호출 스택을 통해 제어합니다.

  • 스크립트가 함수를 호출하면 인터프리터가 호출 스택에 추가한 다음 함수를 수행
  • 해당 함수에 의해 호출된 함수는 호출 스택에 추가되고 호출이 도달하는 위치에서 실행
  • 함수가 끝나면 인터프리터는 스택을 제거하고 메인 코드 목록에서 중단된 실행을 다시 시작
  • 할당된 스택 공간보다 더 많은 공간을 차지하면 Stack Overflow 에러 발생
function one() {
  two();
  console.log("called one");
}

function two() {
  three();
  console.log("called two");
}

function three() {
  console.log("called three");
}

one();

 

위 예제를 실행하게 되면 아래와 같은 결과를 볼 수 있습니다.

 

예제 결과

 

그림과 같이 one이 호출되면서 스택에 올라가게 됩니다. 스택에 올라간 one 함수가 실행되면서 two를 호출하고 two가 스택에 쌓이면서 one의 실행을 멈추고 two가 실행되게 됩니다. 마찬가지로 two는 three를 호출하여 스택에 쌓게 합니다.

 

각 함수가 호출될 때마다 스택에 쌓이면서 최상단에 있는 함수가 완료되면 그 스택을 제거하고 다음 함수가 마저 실행되는 데 이것이 자바스크립트의 호출 스택 동작 방식입니다.

 

단일 스레드는 위와 같이 단일 호출 스택만 존재하기 때문에 동시에 여러 작업을 수행할 수 없습니다. 서버에 데이터를 요청하는 것처럼 작업이 오래 걸리는 함수를 호출하면 다른 함수의 실행에도 지장이 가게 되는데 이를 해결하는 방법으로 비동기 콜백이 존재합니다.

 

 

Event Loop

 

이벤트 루프(Event Loop)와 브라우저의 환경

출처: https://poiemaweb.com/js-event

 

자바스크립트 엔진은 위에서 알아봤듯이 호출 스택을 이용하여 작업을 동기적으로 수행합니다. 동시성 작업을 위한 비동기 처리는 위 그림처럼 자바스크립트가 아니라 브라우저, Node.js의 Libuv 라이브러리에서 지원하는 이벤트 루프를 이용하여 수행하게 됩니다.

 

while(queue.waitForMessage()){
  queue.processNextMessage();
}

 

이벤트 큐(Event Queue)는 메시지 큐, 태스크 큐라고도 불리며 처리할 메시지의 대기열입니다. 각각의 메시지에는 메시지를 처리하기 위한 함수가 연결되어 있으며 이벤트 루프에 의해 선입선출 방식으로 호출 스택에 추가됩니다.

 

이벤트 루프는 호출 스택과 이벤트 큐에 함수가 있는 지 반복해서 확인하며 호출 스택이 비어있다면 이벤트 큐의 작업을 호출 스택으로 이동하고 실행시킵니다.

 

const func1 = () => {
  console.log("1번 함수 호출");

  func2();
};

const func2 = () => {
  setTimeout(() => {
    console.log("2번 함수 호출");
  }, 0);

  func3();
};

const func3 = () => {
  console.log("3번 함수 호출");
};

func1();

결과

위 코드는 1번 함수가 2번 함수를, 2번 함수는 3번 함수를 호출하게끔 작성되었습니다. 하지만 결과는 예상과 다르게 2번 함수의 로그가 가장 마지막으로 찍힌 것을 알 수 있습니다.

 

  • func1과 func2가 호출 스택에 쌓인다.
  • func2의 setTimeout이 호출된다.
  • setTimeout에 지정된 최소 지연 시간 동안 지연되며 그 사이에 func3이 호출된다.
  • setTimeout에 이벤트가 발생(지연 시간의 만료)하면 이벤트 큐로 이동한 후 호출 스택이 비면 호출 스택으로 이동되어 실행된다.

setTimeout은 매개값으로 콜백 함수와 지연 시간을 가지며 기본값은 0입니다. 지연 시간이 0이라면 바로 실행되는 게 아닌가 할 수 있지만 실제 실행 시점은 이벤트 큐에서 대기 중인 작업의 수에 따라 다릅니다. 지연 시간은 실행에 보장되는 시간이 아니라 최소 지연 시간입니다.

 

자바스크립트는 논 블로킹 방식으로 작업을 수행합니다. 자바스크립트는 이벤트와 콜백을 통해 작업을 수행하기 때문에 서버에 데이터를 요청하고 응답을 기다리면서도 클릭, 입력 등의 작업을 처리할 수 있습니다.

 

참고링크
https://poiemaweb.com/js-event
https://developer.mozilla.org/ko/docs/Web/JavaScript/EventLoop
https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

'🌐Web > Javascript' 카테고리의 다른 글

스코프  (0) 2022.04.02
타입 변환  (0) 2022.03.27
== vs === vs typeof  (1) 2022.03.17
자바스크립트 Value & Reference  (0) 2022.02.27
자바스크립트의 데이터 타입  (0) 2022.02.24
Comments