[JS] 자바스크립트 동작원리

양주영·2022년 11월 24일
0

javascript

목록 보기
38/42

01. 개요

자바스크립트가 어떻게 내부적으로 동작하고, 비동기 기반으로 작동하는지 또 원리는 무엇인지에 대해서 알아보려고 합니다.
자바스크립트가 어떠한 언어이고, 블로킹, 논 블로킹 중에 어떤 방식으로 프로그래밍을 실행하는지 알아볼까요?



02. 블로킹 / 논 블로킹 이란 무엇일까요~

그림은 블로킹 / 논 블로킹의 이미지입니다.
Blocking이란, 자신의 작업을 진행하다가 다른 주체의 작업이 시작되면 다른 작업이 끝날 때까지 기다렸다가 자신의 작업을 시작하는 것이고,
Non-Blocking은 다른 주체의 작업에 관련없이 자신의 작업을 하는 것을 뜻합니다.

자바스크립트는 싱글스레드이지만 논 블로킹으로 프로그래밍이 실행되는데요.
자바스크립트는 메인스레드 하나로 구성되어 있습니다.
이 말의 뜻은 한번에 하나의 작업만을 수행할 수 있음을 의미합니다. 
다른 작업이 끼어들거나 먼저 수행할 수 없으므로 비동기나 동시성은 본래 자바스크립트의 성질이 아닌거죠. 
그럼 어떻게 동시성을 가진 함수들을 사용할 수 있었는가에 대해 알아보도록 합시다!



03. 자바스크립트 엔진이 필요한 이유는?

동작원리를 알기 전에! 자바스크립트 엔진이 무엇인지 왜 필요한지에 대해서 알아봅시다.
자바스크립트 엔진은 왜 필요할까요?
당연하게도 자바스크립트를 실행하기 위해서인데요!
자바스크립트 엔진은 자바스크립트 코드를 해석하고 실행하는 인터프리터입니다.
그리고, 자바스크립트 엔진을 내장한 웹브라우저는 자바스크립트가 실행될 수 있는 환경인 실행 환경이라고 할 수 있고, 영어로는 런타임이라고 합니다.
자스 엔진은 v8, rhino, spidermonkey 등 다양하게 있지만 이 중에서도 가장 대표적인 예는 구글에서 만든 v8 엔진이 있습니다.
C++로 작성되었으며, 구글이 개발한 오픈소스이고, Google Chrome, Electron, Node.js에서 사용합니다.

SpiderMonkey : 파이어폭스
V8 : 크롬, Node.js
Webkit : 사파리
Chakra : 엣지


자바스크립트 엔진에는 메모리힙과 콜스텍이 있습니다.

Memory heap : 메모리 할당이 일어나는 곳, 우리가 선언한 변수들이 어디에 저장되어 있는지 기록하는 장치
Call stack : 코드 실행에 따라 호출 스택이 쌓이는 곳, 우리가 작성한 js 파일을 기계어로 바꿔서 컴퓨터가 실행할 수 있게 해줌



04. 콜스텍이 무엇이고, 어떻게 실행되나요?

먼저 콜스텍이란 무엇인지 알아봅시다.
( 실행 컨텍스트라는 것이 무엇인지 알아야 하는데, 
실행 컨텍스트 : 실행할 코드에 제공할 환경 정보들을 모아놓은 객체라고 생각하면 됩니다. )
콜스텍은 콜이 스택처럼 쌓입니다.
Call이 쌓이는 것이고, callfunction을 호출하는 것입니다.
윗방향으로 쌓이게 되고, 아랫방향으로 실행됩니다.
콜스텍을 통해서 우리가 어떤 함수를 지금 실행하고 있구나를 알게 됩니다.

왼쪽 코드가 어떻게 동작이 될 거 같나요?
제일 처음으로 모든 코드를 가지고 있는 전역 컨텍스트 anonymous가 담깁니다.
그 다음에 first가 호출이 됩니다. 
여기서 콜 스텍은 호출이 될 때 담긴다고 생각하면 됩니다.
first가 담기고 first로 갔더니 second가 호출이 되고
seond로 갔더니 third가 호출이 됩니다.
그리고 third로 갔더니 console.log(‘세번째’)가 호출이 됩니다.
호출스텍에 다 쌓이고 나서 console.log(‘세번째’)가 실행이 되고,
실행되면서 console.log(‘세번째’)가 빠져나갑니다.
third()가 빠져나가고 second()로 왔더니 third()가 빠지고 console.log(‘두번째’)가 실행됩니다.
실행되면서 console.log(‘두번째’) 빠져나가고
second()가 빠져나갑니다.

이렇게 콜스텍이 무엇인지, 어떻게 실행되는지 알아보았고 다음에는 비동기 처리는 어떻게 하는지 알아봅시다.



아까와는 다른 코드인데 어떻게 실행될 거 같나요?

  1. 맨 첫줄 실행됩니다. console.log(‘시작’)
  2. SetTimeout 은 바로 실행할 수 없기 때문에 대기실로 보냅니다 -> Web API 에게 비동기 작업을 위임합니다.
    여기서 Web API는 자바스크립트 엔진이 아닙니다. Web API는 브라우저에서 제공하는 api로, dom, ajax, timeout등이 있습니다. call stack에서 실행된 비동기 함수는 Web API를 호출합니다.
  3. 그 다음 밑에 줄 실행합니다. console.log(‘끝’)
  4. Web API는 3초 후에 setTimeout 비동기 작업을 수행하고, 콜백 함수를 이벤트 루프를 통해서 콜백 큐에 넘겨주게 됩니다.
    여기서 Web API에서 작업이 끝나면 이벤트 루프를 통해서 콜백함수를 콜백 큐에 밀어 넣습니다.
  5. 콜스텍이 비어있을 때, 콜백 큐에서 대기하고 있던 콜백함수를 콜스텍으로 넘겨줍니다.
  6. 콜스텍에 쌓인 콜백함수가 실행되고, 콜스텍에서 제거됩니다.


05 런타임 환경에서 어떻게 비동기 코드가 실행되는지 정리해볼게요

  1. 코드가 호출스택에 쌓인 후, 실행되면 자바스크립트 엔진은 비동기 작업을 Web API에게 위임합니다.
  2. Web API는 해당 비동기 작업을 수행하고, 콜백 함수를 이벤트 루프를 통해서 태스트 큐에 넘겨주게 됩니다.
  3. 이벤트 루프는 콜스택에 쌓여있는 함수가 없을 때, 태스크 큐에서 대기하고 있던 콜백함수를 콜스택으로 넘겨줍니다.
  4. 콜스택에 쌓인 콜백함수가 실행되고, 콜스택에서 제거됩니다.


06 정리

마지막으로 정리를 해보자면,

  • 자스 런타임에서는 비동기를 지원하지 않지만, 
    동시성을 보장하는 비동기, 논블로킹 작업은 자스 엔진을 구동하는 런타임 환경 ( 브라우저, nodejs ) 에서 지원합니다. 자스는 코드를 그대로 실행하기만 할 뿐. 이를 실행하는 환경(런타임 환경)에서 이벤트를 체크 해주고, 비동기 작업을 처리해주게 됩니다.
  • 자바스크립트는 싱글스레드이므로 멀티스레드 환경을 가정하고 모든 비동기코드가 의도된 정확한 타이밍에 실행될 것 이라고 생각해선 안됩니다. 따라서 이를 주의한 설계가 필요합니다.


  • 호출스택에 무거운 연산을 둬서 정체시키면 이는 사용자 경험에 안좋은 영향을 끼칩니다.
  • 마찬가지로 태스크큐에 많은 이벤트가 쌓은 경우에도 사용자 경험을 저하시킵니다.


참고 :
https://www.youtube.com/watch?v=v67LloZ1ieI
https://www.youtube.com/watch?v=QFHyPInNhbo
https://joshua1988.github.io/web-development/translation/javascript/how-js-works-inside-engine/

profile
뚜벅뚜벅

1개의 댓글

comment-user-thumbnail
2023년 1월 6일

멋져여!

답글 달기