JavaScript/동작원리

자바스크립트 - 동작 원리

태기의삶 2020. 7. 5. 20:23

 

 

자바스크립트는 싱글 스레드 프로그래밍 언어이다.

싱글 스레드 런타임을 가지고 있다는 의미이다.

이것은 결국 한 번에 하나의 싱글 콜 스택(Call Stack)만을 가지고 있다는 말을 뜻한다.

여기서 싱글 스레드란?

하나의 프로그램은 동시에 하나의 코드만 실행할 수 있다는 것을 말한다.

 

그렇다면 자바스크립트는 어떻게 작동할까?

Call Stack 그림을 보면서 이해해보자.

Call Stack은 Data Structure(자료 구조)로 작성한 코드가 실행되는 순서를 기억하고 있다.

함수를 실행하려면 Stack(스택)에 해당하는 함수를 집어넣게 되고, 함수에서 리턴이 일어나면, 스택의 가장 위쪽에서 해당 함수를 꺼내게 된다.(LIFO)

이것이 Call Stack이 하는 일의 전부이다.

 

이 코드를 실행하면 실행되는 코드 자체를 말하는 main() 함수를 스택에 집어넣게 된다.

그러면 이제 main() 안에 들어있는 함수들이 정의가 된다.

마지막 줄에 printSquare(4)를 만나게 되는데, 여기서 함수를 호출하고 있으니 스택에 함수를 추가한다.

순서대로 호출하는 함수들을 Stack(스택)에 추가한다.

먼저 printSquare(4) 함수가 호출되고, 그 안에 square(n) 함수가 변수 squared에 담기고, console.log(squared) 담겨서 또 함수가 호출된다.

호출이 되면, square() 함수 안에 있는 multiply() 함수가 마지막으로 호출된다.

이제 함수 내에서 무언가를 return할 때마다 우리는 스택 위에서 하나씩 꺼내게 된다.

즉, pop()을 하게 된다.

먼저 multiply() 함수가 a * b를 반환하고 Stack(스택)에서 사라진다.

그러고 나서, square() 함수가 multiply()가 반환한 값 a * b를 가지고 반환하고 Stack(스택)에서 사라진다.

square() 안에 있는 console.log(squared)도 스택에 쌓이고 암묵적으로 값을 리턴하고 사라진다.

console.log(squared)가 사라지면 printSquare(n) 함수도 같이 사라지고 최종적으로 콘솔 창에 반환된 값이 찍히게 된다. 

이렇게 함수의 마지막 줄에 도달했으면 끝이 난다.

이 방식은 자바스트립트가 동기적으로 동작하는 원리이다.

 

그렇다면 자바스크립트에서의 비동기는 어떻게 동작하는 것인가?

이번에도 그림을 통해 이해해보자.

이 코드 역시 실행하면 실행되는 코드 자체를 말하는 main() 함수를 스택에 집어넣게 된다.

그러고 나서, console.log(hi)가 실행이 되고 stack(스택)에 쌓인 후, hi가 콘솔 창에 출력된다.

hi가 출력이 되면, stack(스택)에서 console.log(hi)가 사라지고, setTimeout을 실행한다.

여기서 setTimeout()브라우저에서 제공하는 API(web API라고도 한다)이다.

즉, 이 말은 자바스크립트가 실행되는 런타임 환경에서 별도의 API가 존재한다는 뜻이다.

브라우저가 web API에서 타이머를 실행시키고 카운트 다운을 시작한다.

이건 setTimeout 호출 자체가 완료되었다는 의미이므로, 이제 stack(스택)에서 setTimeout()은 사라진다.

그러고 나서, console.log('JSConfEU')를 실행하고 stack(스택)에 추가되고, 'JSConfEU'를 출력 후 stack(스택)에서 지워진다.

이제 web API에서 실행하고 있는 타이머만 남았다.

하지만, 이 타이머는 5초 뒤에 종료되는데, 갑자기 작성된 코드에 끼어들면 절대 안 된다.

이제 여기서 task queue 또는 callback queue가 활약할 차례이다.

 

모든 Web API는 작동이 완료되면 callback을 task queue에 밀어 넣는다.

 

여기서 이제 이벤트 루프(Event Loop)가 등장한다.

이벤트 루프(Event Loop)란?

call stack과 tack queue를 주시하는 작은 파트를 말한다.

즉, stack(스택)이 비어있으면, task queue의 첫 번째 call back부터 stack(스택)에 쌓아 효과적으로 실행할 수 있게 해 준다.

보시는 봐와 같이 현재 stack(스택)이 비어있고, tack queue에는 callback이 하나가 있다.

여기서 이제 이벤트 루프(Event Loop)가 자신이 할 일을 생긴 것을 인지하고 callback을 stack(스택)에 넣기 시작한다.

여기서 stack(스택)은 엄연히 자바스크립트 영역이라는 것을 명심해야 한다.

이제 다시 자바스크립트 엔진(V8)으로 돌아가서, console.log("there")을 실행한다.

이제 콘솔 창에 there이 찍히고 stack에서 모두 사라진다.

이렇게 자바스크립트의 비동기 동작이 어떻게 되는지도 알아보았다.

 

📝 이 글을 쓰면서 느낀 점

이전엔 자바스크립트는 비동기적인 언어라고 생각했다.

사실 동기인지 비동기 인지도 잘 몰랐던 것 같다.

하지만, 블로그를 작성하면서 자바스크립는 싱글 스레드인 동기적인 언어이고, 이 자바스크립트가 브라우저에서 별도의 API를 통해서 비동기 처리를 하는 것을 이제야 깨닫게 되었다.

[유튜브에서 자바스크립트 작동 원리 영상을 보고 직접 정리한 내용입니다.]