기주

자바스크립트 런타임 동작원리 알아보기 본문

프로그래밍언어/javascript

자바스크립트 런타임 동작원리 알아보기

기주그지마 2025. 2. 16. 17:56

 

자바스크립트 런타임 알아보기

 

자바스크립트 런타임인 nodeJS와 브라우저에는 자바스크립트 엔진외에도 백그라운드(libuv), 이벤트 큐, 이벤트 루프 등의 라이브러리가 존재한다. 그렇다면 자바스크립트 엔진외의 다른 라이브러리들은 왜 필요한걸까?

 

자바스크립트가 가진 한계점들을 보완하기위해서이다. 자바스크립트만으로는 싱글 스레드 블로킹 이슈와, OS수준의 작업, 파일 시스템 접근 불가하다는 문제가 있기 때문이다.  

 

 

 

 

자바스크립트는 싱글스레드 언어이다.

 

-> 따라서 두 개 이상의 연산이나 함수를 동시에 실행할 수 없다. 하나의 연산이 실행 중이면, 쓰레드가 block 된다. 간단한 함수 실행에 의한 쓰레드 block은 체감하기 어렵지만, 시간이 오래 걸리는 작업(네트워크 요청, DB Query, 파일 시스템 제어 등)이  메인 쓰레드를 block하고 있으면, 심각한 자원 낭비와 성능 저하로 이어진다. 따라서, 메인 쓰레드를 block하지 않고 이런 작업들을 수행할 수 있는 방안이 필요하다.


그래서 nodejs에서는 c++로 만든 libuv라이브러리를 통해 브라우저에서는 fetch와 같은 웹 API를 통해 백그라운드에서 처리한다. 이렇게 메인스레드가 아닌 백그라운드에서 처리하는 작업을 "비동기 작업"이라고 부른다.




 콜백함수란 무엇인가?

메인 스레드에서 비동기 함수를 만나면 실제 처리를 백그라운드로 넘긴다. 그리고 백그라운드에서 작업이 완료된다면 그 결과를 메인 스레드에 알려줘야 한다. 이는 메인 스레드가 요청한 작업이기 때문이다. 
그래서 비동기 함수 호출 시 처리 완료 시 메인 스레드에서 실행할 함수를 함께 전달해야 된다. 그것이 콜백 함수이다.
즉, 비동기 작업이 완료되었을 때 메인 스레드에서 실행할 함수를 콜백함수라고 부른다.

 

 

 

이벤트 루프의 필요성

콜백 함수는 메인스레드에서 백그라운드로 잠시 전출보낸 함수. 언젠가는 다시 메인 스레드로 돌아와야 한다.
하지만 여기서 콜백함수가 다시 돌아와야할 타이밍이 애매해 질 수 있는데 메인 스레드에서 다른 연산이 작업중일 수 있기 때문이다. 그래서 콜백함수가 돌아올 시점을 정해주는 역할이 필요한데 이 역할을 하는 것이 이벤트 루프이다.

 

 

 

 

 

이벤트 루프의 동작 원리

 

메인 스레드에서 실행되는 모든 함수들은 콜스택이라는 공간에 LIFO 형태로 차곡차곡 쌓인다. 함수가 호출되면 콜스택에 push되고, return 문을 만나면 pop되는 구조이다. 콜스택에 비동기 함수가 들어오면 그 즉시 pop하여 백그라운드로 전달한다. 비동기 함수가 백그라운드에서 처리되는 동안 콜스택에서는 다음 함수가 계속해서 실행되고 있기 때문에 single thread blocking 문제를 해결할 수 있다. 이후, 백그라운드에서 비동기 처리가 완료되면, 호출 시점에 전달한 콜백함수가 이벤트 큐라는 공간에 FIFO 구조로 쌓인다.

 

여기서 이벤트루프는 이벤트 큐에서 콜스택으로 콜백함수를 이동시켜준다. 이벤트 루프는 call stack이 완전히 비어있는지 수시로 확인하여, 비어있다면 이벤트 큐에서 콜백함수를 shift한 다음, 콜스택에 push 해주는 역할을 한다. 

 

다시 정리하자면, 모든 함수 호출들은 콜스택에 LIFO구조로 쌓이고, 비동기 함수는 콜스택에 들어오는 즉시 백그라운드로 보내진다. 백그라운드에서 처리가 완료되면 콜스택 함수들은 이벤트 큐에 FIFO구조로 쌓이며, 이벤트 루프가 신호를 줄 때까지 기다린다. 이벤트 루프는 콜스택이 비어있는지 수시로 확인하며, 비어있을 경우, 이벤트 큐에 쌓인 콜백 함수를 shift하여 콜스택에 push한다.