JavaScript | 자바스크립트 작동 원리(Event Loop와 Call Stack, Web API, Callback Queue)

Ryan·2021년 1월 23일
119

JavaScript

목록 보기
18/18
post-thumbnail

자바스크립트를 다루는 사람은 많지만, 자바스크립트의 작동 원리를 명확히 알고 사용하는 사람은 많지 않은 것 같다.
그래서 정리한 내용을 함께 알아보자.

1. 자바스트립트 엔진

: 크롬의 V8엔진에 대해서는 자주 들어봤을 것이다. 그 외에 또 어떤 엔진이 있고 각각의 엔진들이 어떤 방식으로 작동 하는지도 알아보자.

1) 엔진의 역할

: 자바스크립트 엔진은 자바스크립트 코드를 실행하는 프로그램 혹은 인터프리터라고 정의되어 있다. 자바스크립트 엔진은 표준적인 인터프리터로 구현할 수도 있고 또는 정적 컴파일러로 구현할 수도 있다.
또한 두 방식을 합친 JIT 컴파일(just-in-time compilation)로도 구현할 수도 있다.
(즉, 여러 종류의 엔진마다 차이가 있다.)

[여기서 잠깐 단어 정리]
(1) 인터프리터란: 소스 코드를 바로 실행하는 컴퓨터 프로그램으로,
  프로그래밍 언어를 읽어가면서 해당 기능에 대응하는 기계어 코드를 실행하는 방식
(2) 컴파일러란: 소스 코드를 읽기 전에 기계어로 먼저 번역한다.
(3) JIT컴파일러란: 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법이다.
 - 같은 함수가 여러 번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다.

2) 엔진 종류

: 웹 브라우저마다 각각의 다른 엔진을 사용하고 있다.

  • V8 : 구글의 크롬에서 사용되는 엔진이다. C++로 만들어졌으며 오픈소스이다.
  • JavaScriptCore : 사파리용으로 애플이 개발했으며 이 역시 오픈소스이다.
  • SpiderMonkey : 최초의 자바스크립트 엔진으로 모질라 파이어폭스를 지원한다.
V8은 유일하게 바이트코드와 같은 중간 코드를 생산하지 않는다는 차이가 있다.

2. V8 엔진 동작 방식

: 크롬의 V8엔진은 JIT 컴파일에 해당한다.
자바스크립트의 동작 방식에 대해 알아보며 V8의 특징에 대해서도 알아보자.

1) Call Stack

: 자바스트립트에는 싱글 쓰레드 언어이다.
즉 한번에 한개의 일만 처리할 수 있다는 의미이다.

[여기서 잠깐 단어 정리]
(1) 쓰레드란: 운영체제에서 실행중인 하나의 프로그램을 프로세스라 하며 이 프로세스의 작은 단위
 - 쓰레드는 단 한개의 일만 처리할 수 있으며 쓰레드가 여러개 모여 프로세스라고 한다.
 - 두개 이상의 프로세스는 멀티 프로세스, 그렇게 여러 일을 동시에 하는 것을 멀티 테스킹이라 한다.
(2) 콜스택이란: 현재 실행중인 서브루틴(함수)에 대한 정보들을 담아두는 스택구조의 메모리영역
  • 콜스택은 프로세스의 어느 단계에 있는지를 기록하게 된다.
    (더 쉽게 말하면..."나 하나씩 밖에 처리 못하는데 그 중에 몇번째 꺼 처리하고 있어!"가 된다)
const function2 = (x, y) => {
    return console.log(x + y);
}
const function1 = (a, b) => {
  function2(a, b)
}

function1(1, 2); // 실행
  • 위의 함수를 호출하면 아래와 같이 스택이 하나씩 쌓이게 된다.(쌓이는 순서가 결국 진행 순서이다)

  • 위에서처럼 순서대로 위에 쌓인 스택은 위에서부터 처리가 되며 하나씩 삭제해나간다.
    (후입선출 이라고 표현하겠다.)
  • 이렇게 하나씩 처리가 되는데, 크롬 등의 브라우저에서 자바스크립트를 다뤄 본 사람이라면
    '정말 단일 쓰레드로만 처리가 되는게 맞나?' 라는 의문을 가지게 될 것이다.
    이 의문은 아래 브라우저에서 제공하고 있는 또 다른 API들을 이해하면 알 수 있다.

2) Web APIs

: 이것은 자바스크립트 엔진이 아니라 브라우저에서 제공하는 API이다.
콜스택에서 불러온 함수 중 비동기적인 함수이면 Web API 가 이것의 Run함수를 호출한다.
이것을 이해하면 이제 '정말 단일 쓰레드로만 처리가 되는게 맞나?' 라는 의문이 어느정도 해결될 것이다.
비동기적 처리라 했으니 DOM, Ajax, SetTimeout 등이 이것에 해당하며 Web API에서 처리를 끝마친 함수를Callback Queue 으로 이동 시킨다.

예를 들어 SetTimeOut(Function(){}, 5000) 으로 5초짜리 비동기 함수가 있다면 
Web APIs에서 5초짜리 타이머가 생성된다.
5초를 이곳에서 머루른 이후 Web APIs는 이 Run함수를 Callback Queue으로 이동시킨다.

2) Callback Queue(Event Queue, Task Queue)

: Web API 에서 보내진 비동기 처리가 모이는 곳으로 콜 스택과는 다르게 선입선출 되는 특징을 가진다.
여기 모인 비동기함수는 이제부터 이벤트 루프의 감시하에 놓이게 된다.

3) Event Loop

: 제일 중요한 녀석인데 Event Loop는 단 한개의 임무만을 수행한다.
바로 Call StackQueue에를 감시하는 일이다.
감시하다가 Call Stack이 비게 되면 Queue에 쌓인 비동기 함수를 Call Stack으로 보내주는 역할을 한다.
Call Stack이 비어있을 때 Callback Queue 에 쌓여있는 비동기 함수 중 가장 먼저 들어온 함수를 보내준다.

  • 이러한 행동을 틱(tick)이라 부른다.
  • 이벤트 루프를 통해 비로소 동기 함수와 비동기 함수의 순서가 정해진다.

참고영상

profile
"꾸준한 삽질과 우연한 성공"

9개의 댓글

comment-user-thumbnail
2021년 1월 23일

헐! 나 이거 보고 공부해야지 ~~! 감사합니다 상혁님 :)

1개의 답글
comment-user-thumbnail
2021년 1월 23일

이거 개념 어려웠는데 상혁님 글 읽으니까 이해가 잘되네요!!

1개의 답글

와... 노드 공부하는데,,, 자스 궁금해서 읽고있었는데,, 상혁님 글이였어.. 멋있어요.. :) 감사합니다!!

1개의 답글
comment-user-thumbnail
2023년 12월 4일

잘 읽었습니다. 덕분에 도움이 많이 됐어요~!

답글 달기
comment-user-thumbnail
2024년 1월 31일

감사합니다!! 덕분에 헷갈리던 개념을 바로 잡았습니다!!

답글 달기