[JavaScript]자바스크립트 런타임

Mintaek·2023년 9월 19일
0
post-thumbnail

자바스크립트 런타임

런타임 이란?

프로그래밍 언어가 구동되는 환경. Node.js나 크롬 등의 브라우저들은 자바스크립트가 구동되는 환경이기 때문에, Node.js나 브라우저들을 자바스크립트 런타임이라고 한다.

Javascript : 싱글 스레드, 논-블로킹 언어

자바스크립트는 싱글 스레드, 논-블로킹 언어이다.

싱글 스레드

하나의 힙 영역과 하나의 콜 스택을 가진다.

  • 한 번에 한 가지 일 밖에 하지 못한다는 의미.
  • Ex) 네트워크 요청 => 응답이 올 때까지 기다릴 수 밖에 없음.
  • ❗️ : 변수와 객체의 메모리 할당에 사용되는 비정형 메모리.

콜 스택

함수가 실행되는 순서를 기억한다.

  • 함수를 실행하려면 스택의 가장 위에 해당 함수를 넣게 되고, 함수에서 리턴이 일어나면 스택의 가장 위쪽에서 함수를 꺼낸다.

콜 스택 예제

콜스택예제

논-블로킹

싱글 스레드는 스택이 하나밖에 없기 때문에, 한 번에 한 가지 일 밖에 할 수 없다.

블로킹

❓ 이게 왜 문제가 되는가

웹 브라우저에서 코드가 실행되는데, 코드가 종료될 때까지 유저가 클릭을 해도 어떠한 반응을 하지 않는 상태가 되버린다.

  • 사용자에게 원활한 UI를 제공해야 한다면, 콜 스택이 멈추게 해서는 안된다.
  • 콜 스택이 멈춘 상태 : 블로킹 상태 라고 한다.

블로킹 예제

const fs = require('fs');

// 파일을 동기적으로 읽기
const data = fs.readFileSync('file.txt', 'utf8');

console.log(data);
console.log('파일 읽기가 완료되었습니다.');
  • 위 예제는 파일을 동기적으로 읽으며 파일 읽기가 완료될 때까지 다음 코드로 진행하지 않는다.

  • 블로킹 상태를 해결하는 방법
    => 논-블로킹, 비동기 콜백을 사용하는 것.

논-블로킹

const fs = require('fs');

// 파일을 비동기적으로 읽기
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});

console.log('파일 읽기 요청을 보냈습니다.');
  • 프로그램은 파일 읽기 작업이 진행되는 동안 다음 코드로 바로 진행하므로 블로킹되지 않는다. 즉, "파일 읽기 요청을 보냈습니다." 메시지가 먼저 출력되고, 파일 읽기가 완료된 후에 데이터가 출력된다.

자바스크립트 런타임

크롬의-자바스크립트-런타임

  • 위의 그림은 크롬의 자바스크립트 런타임을 표현한 그림이다.
  • 자바스크립트 런타임은 자바스크립트 엔진, Web API, 콜백 큐, 이벤트 루프, 렌더 큐로 구성된다.

자바스크립트 엔진: V8

자바스크립트 런타임은 자바스크립트 엔진을 포함하고 있다. 크롬은 V8을 자바스크립트 엔진으로 사용하고 있다.

  • 구글에서 개발한 오픈소스 자바스크립트 엔진. C++로 만들어져 있으며, Node.js, 크롬 브라우저 등에서 사용된다.

  • V8은 싱글 스레드를 제공한다. 싱글 스레드는 하나의 콜 스택(Call Stack)과 하나의 힙(Heap)을 제공. 콜 스택은 위에서 이야기했듯이 함수의 호출 순서를 저장. 힙은 할당된 메모리들이 저장되는 영역.

하나의 콜 스택을 가지고 있다는 말은 한 번에 하나의 동작만 할 수 있다는 말이다.

그렇다면, V8 소스에는 이러한 메서드들이 정의되어 있지도 않는데, setTimeut() 이나 ajax, DOM 이벤트 등 콜백으로 비동기 동작을 하는 코딩하는 것은 무엇일까?

  • 예를 들어, setTimeout(..., 1000)가 호출되었을 때, 어떤것이 1초를 카운트하고 1초 후에 콜백 함수를 실행시킬까? 바로 Web API 이다.

Web API

  • Web API는 자바스크립트 엔진에서 정의되지 않았던 setTimeout이나 HTTP 요청 메서드, DOM 이벤트 등의 메서드를 지원.

콜백 큐

  • 콜백 큐는 Web API 결과값을 쌓아두는 큐.
  • 예를 들어 자바스크립트에서 setTimeout(cb, 1000)을 호출하게 되면 Web API는 타이머를 동작시켜 1초 후에 콜백 큐에 cb를 쌓는다.

이벤트 루프

  • 이벤트 루프의 역할은 콜 스택과 콜백 큐를 주시하는 것.
  • 콜 스택이 비어있으면 큐의 첫 번째 콜백을 스택에 쌓아 효과적으로 실행할 수 있게한다.
  • 이벤트 루프는 콜 스택이 비어질 때까지 기다린 후 콜백 큐에 있는 콜백을 콜 스택에 넣어주는 역할을 한다.
  • Web API의 콜백이 완료되었다면 콜백은 큐에 쌓이게 되고, 이벤트 루프에 의해서 실행된다.

setTimeout(..., 0) / ajax

setTimeout

setTimeout는 정확히 얼마 후 동작하겠다는 의미가 아니라 얼마 후 동작하는 최소 시간을 보장한다는 의미가 더 정확하다.

  • 이유는?
    정해진 시간 후 콜백이 콜백 큐에 쌓이는데, 콜백 큐에 쌓인 콜백이 콜 스택에 들어오기 위해서는 콜 스택이 비어 있어야 한다. 정해진 시간이 지난 후 그 이후에 콜 스택이 비어있을 때 setTimeout의 콜백이 실행된다.

setTimeout 예제

function Test(){
    console.log('하나');
    setTimeout(()=> console.log('둘'), 0);
    console.log('셋');
}

Test();
  • 위의 예제에서 setTimeout(()=> console.log('둘'), 0) 의미는 0초 후 '둘'을 출력해줘 라는 의미이다. 그래서 Test() 함수를 호출했을 때에, '하나' , '둘' , '셋' 이 차례대로 출력될 것 같지만, 그렇지 않다. 실제 출력값은 '하나' , '셋' , '둘' 이다.

  • 이유는 콜 스택이 비어있지 않기 때문.

ajax

ajax도 setTimeout과 동일하게 동작한다.

ajax 예제

function foo(){
    console.log('hi')
    $.get('url', function cd(data){
        console.log(data)
    })
    console.log('bye')
}
foo();

// Console
'hi'
'bye'
{ some : 'foo' }

참고

https://beomy.github.io/tech/javascript/javascript-runtime/

https://hanamon.kr/javascript-%EB%9F%B0%ED%83%80%EC%9E%84-%EC%9E%91%EB%8F%99-%EB%B0%A9%EC%8B%9D-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%99%80-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84/

https://ko.wikipedia.org/wiki/V8_(%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8_%EC%97%94%EC%A7%84)

profile
Slow and Steady Wins the Race

0개의 댓글

관련 채용 정보