JavaScript의 내부동작원리는?

2022. 1. 12. 00:00Web

 

안녕하세요. brandy 입니다. Javascript를 공부하던 도중 Call stack의 개념에 대해서 알게 되었고, Event Loop 등 관련한 개념들을 정리해보고자 합니다.

 

이전에는 학교에서 자바스크립트는 HTML 페이지와 어떤 방식으로 상호작용 하는지만 알았다면,

내부 동작 원리를 이해하고자 합니다. 이제는 어떤 엔진으로 돌아가고 자바 시간에 배운 스레드와 맞물려 이해해보고자 합니다.

 

* Single Thread : 일하는 주체가 1개 > 하나의 작업만 처리 가능

그런데 자바스크립트는 동시에 많은 작업을 처리하는 '것처럼 보인다'

왜 그럴까요? 바로 Event Loop 에 의 의해 가능한 일입니다.

 

 

 

자바스크립트 엔진은 Memory Heap 영역과 Call Stack 영역으로 이루어져 있습니다.,

Memory Heap에서 변수와 객체에 대한 모든 메모리 할당이 이루어지며,

 

Call Stack은 코드가 실행될 때 호출 스택이 쌓이는 공간입니다. 단일 호출 스택으로 한 번에 하나의 일만 처리합니다.

 

 

브라우저마다 같은 코드여도 실행결과가 다릅니다.

그 이유는 각각의 브라우저마다 엔진을 다르게 사용하기 때문인데요, 브라우저도 단순히 하나의 엔진으로만 구성되지는 않습니다.

DOM,Ajax,setTimeOut 등 브라우저에서 제공하는 Web API가 있으며 Web API의 호출을 통제하기 위한 EventQueue와 Event Loop도 존재합니다.

 

※ 자바스크립트의 경우 V8엔진을 사용합니다. 구글이 만들었으며 오픈소스이고 C++로 제작됩니다.

구글 크롬에서 사용중이며 node.js의 런타임으로도 사용됩니다.

 

 

 

Call Stack에 대해 좀 더 알아보도록 합니다.

일단 Call Stack도 Stack이므로 LIFO(Last In First Out 후입선출)의 구조를 가집니다.

스택에 마지막으로 입력(push)된 자료가 가장 먼저 pop 되어 나옵니다.

 

function multiply(x,y) { 
    return x*y; 
} 

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

 

printSquare(5); 함수가 실행되면 이후의 단계는?

 

위에서 자바스크립트는 단일 호출 스택이라고 했습니다. 이들의 장단점은 무엇일까요?

(+) 멀티스레드 환경에서 발생하는 복잡한 시나리오(데드락 교착상태)를 고려할 필요가 없다.

(-) 단일(하나)의 호출 스택만 있는데, 하나의 함수 처리가 엄청 느려서 다른 함수 실행에 지장을 준다면?

만약 브라우저가 호출 스택에서 많은 작업을 처리하기 시작하면 오랜 시간동안 응답을 멈출 수 있습니다.

그래서 브라우저는 이 상황에서 웹 페이지를 종료할지에 관한 여부를 묻는 오류 메시지를 표시합니다.

 

단일 호출 스택의 해결 방법은 무엇일까요?

비동기 콜백(Asynchronous Callbacks) 사용하기.

우리의 코드 일부를 실행하고 나중에 실행될 콜백(함수) 제공. 특수한 시점에 실행되므로

console.log와 같은 동기 함수는 스택 안에 바로 push 될 필요가 없습니다.

 

그러나 스택이 아니라면 이 Call Back 함수들은 누가 관리하는 걸까요?

자바스크립트는 이벤트큐(Event Queue)를 가지고 있습니다. 이벤트큐에서 처리할 메시지 목록과 실행할 콜백 함수들의 리스트입니다.

 

 

1) 예를 들어 버튼 클릭과 같은 이벤트가 발생하면 DOM 이벤트, http 요청, setTimeout 등과 같은 비동기 함수는 C++로 구현된 Web API를 호출

2) Web API는 콜백 함수를 이벤트 큐(콜백 큐)에 push

3) 이벤트 큐는 대기하다가 스택이 텅 비는 시점에 이벤트 루프를 돌림(스택에 넣는다)

> 이벤트루프의 기본 역할은 큐와 스택을 지켜보다가 스택이 비는 시점에 콜백을 실행시켜줌

 

 

때문에 자바스크립트는 싱글 스레드 기반의 언어라고도 볼 수 있지만,

자바스크립트가 구동되는 브라우저 환경의 관점에서 본다면 여러 개의 스레드로 비동기적으로 작동하는 언어라고도 볼 수 있습니다.

 

※ 동기 (Synchronous) vs 비동기(Asynchronous)

동기 : 요청 후 응답을 받아야 다음 동작 실행하는 방식

자바스크립트는 동기 방식으로 진행이 되는데, 위에서 말했던 단일 호출 스택이기 때문에 하나의 함수를 처리하는데 오랜 시간이 걸립니다.

 

그래서 비동기 방식이 필요한 것이죠!

비동기 : 요청을 보낸 후 응답과 관계없이 다음 동작을 실행하는 방식

예를 들어, 웹 페이지를 사용자에게 보여줄 때 해당 웹 페이지에 있는 모든 데이터를 받고 나서야 화면이 보여진다면, 서버에서 데이터를 모두 받아올 때까지 시간이 오래 걸리고 사용자 입장에서 웹 페이지를 보는데 너무 느리다.

> 데이터를 받아오는 일을 하는 도중에 웹페이지의 기본 레이아웃을 먼저 보여주고,

보여줄 것들을 나중에 보여주는 것이 사용자 측면에서는 더 바람직하다. 약간 멀티로 일을 하는 것 같죠?

이 점으로 비추어 봤을 때 자바스크립트는 싱글 스레드로 동작하는걸까? 멀티 스레드로 동작하는걸까?에 대한 의문점이 생겼던 것 같네요.

 

비동기적 callback함수 사용 or ES6 Promise, ES8 async await

 

 

 

저도 작성하면서 공부를 했던지라, 글이 좀 중구난방한 것 같네요..ㅜㅜ

나중에 기회가 된다면 좀 더 간결한 글로 자바스크립트 내부 동작 원리에 대해 다뤄보도록 하겠습니다.

 

잘못된 부분이 있다면 언제든지 지적 환영입니다 !

읽어주셔서 감사합니다 :)

 

 

 

참고 https://new93helloworld.tistory.com/358