[JavaScript] 자바스크립트 런타임 (Javascript Runtime)

배고픈메꾸리·2020년 12월 25일
2

Advanced JavaScript

목록 보기
4/10

자바스크립트는 하나의 콜 스택을 가지는 싱글 스레드 프로그래밍 언어이다. 싱글 스레드라는 것은 한 번에 하나의 명령 집합만이 실행된다는 것을 의미한다. 그렇기 때문에 자바스크립트는 동기식(Synchronous)으로 작업을 처리할 수 밖에 없는데 , 이로 인해서 많은 문제가 발생한다.

만약 처리하는데 많은 시간이 걸리는 작업이 있다고 생각해보자. 그 작업이 실행되는 동안 사용자는 아무것도 할 수 없을 것이다.

개발자 도구를 열고 콘솔창에 alert("text") 을 입력해 보자.
메시지가 떠있는 동안에는 스크롤 할 수도 , 다른 버튼을 클릭 할 수도 없다. 이렇듯 시간이 아주 많이 걸리는 작업이 콜 스택에서 빠져나가지 못하고 계속 처리한다면 사용자는 어떠한 일도 할 수 없을 것이다.


자바스크립트 런타임 (Javascript Runtime)

앞에서 언급했듯 자바스크립트 엔진에는 하나의 메모리 힙과 콜 스택이 존재하므로 다른 프로그램이 무언가를 실행하려면 현재 작업이 끝날때 까지 기다려야하는 문제점이 있었다. 그리고 만약 많은 시간이 걸리는 작업을 수행한다면 프로그램이 엄청나게 느려질 것이다.

그렇다면 어떠한 방식이 이를 해결할 수 있을까?
오래 걸리는 일은 백그라운드에서 처리하고 간단하게 처리할 수 있는 작업들만 콜 스택에서 수행한다면 효율적으로 처리할 수 있을것이다. 그리고 이런 일이 가능하게 해주는 것이 바로 자바스크립트 런타임 이다.

Web API

Web API는 브라우저와 함께 제공된다. 웹 API는 HTTP 전송, setTimeout , DOM Event 등과 같은 다양한 작업을 수행할 수 있다. 또한 브라우저에서 캐싱 또는 데이터베이스 저장소를 사용할 수 있게 해준다.

개발자 도구에 들어가서 콘솔창에 window를 입력해 보자.

엄청나게 방대한 양의 객체가 나오는 것을 확인할 수 있는데 이 window객체가 바로 브라우저가 제공하는 Web API 이다. 간단하게 몇가지 요소들만 살펴보자.


스크롤 하다보면 HTTP 호출을 하기 위해서 사용되는 fetch함수 를 발견할 수 있고, 이는 사용자가 직접 사용이 가능하다.

indexedDB는 브라우저에서 사용할 수 있는 작은 데이터베이스이다.

참고로 이는 Application 탭에 들어가서 확인이 가능하다.


마지막으로는 평소에도 예제에 자주 사용되는 setIntervalsetTimeout을 확인할 수 있는데 이 또한 마찬가지로 브라우저에서 제공되는 Web API이다.

위와 같은 함수들은 동기적으로 처리할 경우 심각하게 느려지거나 아예 먹통이 될 수 있는 함수들이다. 그러므로 백그라운드에서 처리하기 위해서 Web API로 따로 빼놓고 사용하는 것이라고 유추해 볼 수 있다 (뇌피셜)

어찌됐건 결론은 Web API를 사용하여 백그라운드에서 비동기적으로 작업을 처리할 수 있고 , 이러한 작업이 끝나면 자바스크립트 엔진(콜 스택)에게 해당 작업이 끝났음을 알려주어 계속해서 작업을 수행해 나갈 수 있게 된다.

이벤트 루프와 콜백 큐 (Event Loop and Callback Queue)

Web API는 브라우저에서 제공되는 함수 및 기타 등등이라고 배웠다. 예를 들어, 코드를 쭉 실행하다가 setInterval 함수가 나온다면 콜 스택은 '이건 내가 모르는건데?' 하고 Web API로 전달한다.
Web API에서는 해당 작업을 자체적으로 처리한 뒤 콜백 큐(Callback Queue) 로 전달한다. 이렇게 콜백 큐로 들어온 작업들은 콜 스택이 비어있을 경우에만 콜 스택으로 이동하게 되는데 이 때 이벤트 루프(Event Loop) 가 콜 스택이 비어있는지 주기적으로 확인하고 콜백 큐에 있는 작업들을 이동시키는 역할을 한다.

말로 설명하면 어려우니까 예제를 보고 이해해보자.

function d(){
    console.log("Hello")
}

function c(){
    setTimeout(d , 3000);
}

function b() {
    c();
}

function a() {
    b();
}

a();

a 함수는 b를 호출하고 b 함수는 c 를 , c함수는 setTimeout(d , 3000)을 수행한다. 그리고 마지막으로는 d 함수에서 console.log("Hello")를 수행한다.

  1. a b c 함수가 순서대로 콜 스택에 쌓이게 된다.
  2. setTimeout(d,3000) 함수를 콜 스택에서 Web API로 이동시킨다.
  3. 콜 스택의 작업들이 마무리되면서 백 그라운드에서는 setTimeout(d,3000) 를 수행한다.
  4. Web API에서 작업이 끝나면 콜백 큐 (Callback Queue)로 이동한다.
  5. 콜 스택에 작업이 없을 경우 콜백 큐에 있는 d를 콜 스택으로 이동시킨다.
  6. d를 수행하고 console.log("Hello")를 수행한다.
  7. 작업을 마치고 콜 스택에서 pop 된다.

그렇다면 만약 setTimeout(d,0) 으로 바꾼다면 결과가 달라질까? 한 번 알아보자.

Web API 에서 바로 콜백 큐로 이동했지만 콜 스택이 비어있기 전에 작업이 이동되지 않는것을 확인할 수 있다 .

profile
FE 개발자가 되자

0개의 댓글