Javascript 콜스택과 이벤트루프 이해하기 | V8 엔진의 비동기 처리 방식

고광필·2022년 1월 28일
1

Front

목록 보기
2/33

https://github.com/yjs03057/33-js-concepts
자바스크립트 개발자가 알아야하는 33가지 개념 중 1번째 콜스택

왜 알아야 하는가?

자바스크립트는 한번에 하나의 작업을 하는 단일 스레드 언어입니다.
콜스택과 이벤트 루프라는 개념은 한번에 하나의 작업을 하는 자바스크립트에서 어떻게 여러 작업을 수행할 수 있는지를 이해하기 위한 개념이라 생각합니다.

동기와 비동기

쉽게 말해 동기적으로 동작한다는 것은 해당 작업의 응답을 받을때까지 기다린다는 뜻이고,
비동기적으로 동작한다는 것은 동시에 여러개의 작업을 한다는 뜻입니다.

자장면 배달부 예시가 많이 나오곤 하는데
동기는 A집에 자장면 배달하고 다 먹을때까지 기다려서 그릇을 가져온 후, 다음 배달을 수행합니다.
비동기는 A집에 자장면 배달하고, A집의 그릇을 기다리지 않고 다른 배달을 수행합니다.
A집이 다먹었다고 전화응답을주면 그때 그릇을 가지러 갑니다.

단일 스레드의 문제점

자바스크립트는 한번에 하나의 작업을 하는 단일 스레드 언어라고 말씀드렸습니다.

A, B두 버튼이 있다고 하겠습니다.
A버튼을 눌러 네트워크 요청을 보내고, 바로 B버튼을 눌러 어떤 이벤트를 실행하겠습니다.
네트워크 요청이 동기적으로 동작한다면 요청의 응답이 굉장히 느리게 돌아올 때
사용자가 추가 조작을 해도 응답을 기다리는중이라서 아무 일도 생기지 않습니다.

물론 이것은 비동기 콜백을 통해서 코드의 일부를 실행하고, 나중에 실행될 콜백함수를 제공해서 해결이 가능합니다.

근데 단일 스레드에서 비동기는 어디로 가고 어떻게 처리되는걸까요?
자바스크립트를 동작하는 V8 엔진의 구성 요소를 통해 이를 알아봅시다.

콜 스택

: 코드 실행에 따른 함수 호출을 기록하는 데이터 구조
ex) 현재 어떤 함수가 동작하는지, 그 함수가 어떤 함수 내에서 동작하는지, 다음에는 어떤 함수가 호출되어야 하는지 등

function a() {
  console.log("a");
  b();
}

function b() {
  console.log("b");
  c();
}

function c() {
  console.log("c");
  d();
}

function d() {
  console.log("d");
  // throw new Error("Hi I'm Error");
}

a();

콜스택은 빈 상태에서 시작되어 자바스크립트가 함수a를 호출하면 콜스택에 a함수를 추가하고 실행합니다. 이후 a함수에 의해 호출되는 모든 함수가 콜스택에 추가됩니다.

빈 콜스택에서 시작해서 함수 호출마다 자동으로 콜스택에 추가되고, 해당 코드가 모두 실행된 후 콜스택에서 자동 제거되어 다시 빈 콜스택으로 끝납니다.

콜스택에 추가되는 항목을 프레임이라 합니다.

[] => [a] => [a, b] => [a, b, c] => [a, b, c, d] => [a, b, c] => [a, b] => [a] => []

Error 부분의 주석을 해제하면 위처럼 어떤 함수에 의해 호출된 함수인지를 알 수 있습니다.

자바스크립트가 실행하는 코드가 비동기 요청이고, 실행할 콜백함수를 넘기면
응답을 받고, 콜백함수를 실행할텐데
단일 스레드 방식에서 실행할 콜백함수는 어디로 가고, 어떻게 처리될까요?

태스크 큐 (비동기는 어디로?)

콜스택에 지금 실행해야하는 코드가 푸시된다면,
태스크 큐에는 나중에 처리할 코드들이 대기하게 됩니다.
콜백 함수나 이벤트 등이 이에 해당합니다.

이벤트 루프 (비동기는 어떻게?)

이벤트 루프는 콜스택과 태스크 큐를 보고 있다가,
스택이 비어 있을 때 큐의 첫 항목을 스택으로 푸시하고
이 작업을 반복합니다.

정리

자바스크립트는 한번에 하나의 작업을 하는 단일 스레드 언어이다
이로 인해 동기적인 로직에서 대기 시간동안 아무 일도 생기지 않는 문제점이 발생한다.
이런 상황은 비동기를 통해 해결할 수 있다.

비동기가 실행되는 원리는
지금 실행할 코드는 콜스택에 들어가 실행된다.
비동기의 경우 나중에 실행할 로직(콜백 함수, 이벤트 등)이 태스크 큐에 들어가 대기한다.
이벤트 루프가 콜스택과 태스크큐를 보고 있다가, 스택이 비어있을 때 큐의 대기 항목을 콜스택에 넣어준다.

참고

profile
이해하는 개발자를 희망하는 고광필입니다.

0개의 댓글