자바스크립트 엔진과 싱글 쓰레드

 

  • 자바스크립트 엔진은 한 번에 하나의 태스크만 실행할 수 있는 싱글 쓰레드 방식으로 동작합니다. 싱글 쓰레드 방식으로 동작하기 때문에 한번에 하나의 태스크만 실행할 수 있습니다. 하지만 브라우저와 Node.js와 같이 백그라운드에서는 멀티 쓰레드로 동작합니다.




이벤트 루프와 테스크 큐

 

이미지 출처 : https://velog.io/@titu/JavaScript-Task-Queue%EB%A7%90%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%81%90%EA%B0%80-%EB%8D%94-%EC%9E%88%EB%8B%A4%EA%B3%A0-MicroTask-Queue-Animation-Frames-Render-Queue



  • 자바스크립트의 특징 중 하나는 싱글 쓰레드로 동작한다는 것입니다. 자바스크립트는 콜 스택과 힙으로 구성된 자바스크립트 엔진, 이벤트 루프, 매크로 테스크 큐, 마이크로 테스크 큐를 통해 동시성을 제공합니다.

 

  • 비동기 방식으로 동작하는 setTimeout의 콜백 함수의 평가와 실행은 자바스크립트 엔진이 담당하지만 호출 스케줄링을 위한 타이머 설정과 콜백 함수의 등록은 실행 환경인 브라우저 또는 Node.js가 담당합니다.



마이크로테스크 큐

 

setTimeout(() => console.log(1), 0);

Promise.resolve()
  .then(() => console.log(2))
  .then(() => console.log(3));

 

  • Promise의 후속 처리 메서드도 비동기로 동작하므로 1 -> 2 -> 3의 순으로 출력될것 같지만 2 -> 3 -> 1 순서로 출력됩니다. 그 이유는 Promise의 후속 처리 메서드의 콜백 함수는 테스크 큐가 아니라 마이크로테스크 큐에 저장되기 때문입니다. 마이크로테스크 큐는 테스크 큐보다 우선순위가 높습니다. 그렇기 때문에 이벤트 루프는 콜 스택이 비면 먼저 마이크로테스크 큐에서 대기하고 있는 함수를 가져와서 실행 컨텍스트 스택에 push하며 마이크로테스트 큐가 비었을 때 테스크 큐에서 대기하고 있는 함수를 가져와 실행합니다.



 

자바스크립트의 비동기 처리 과정

 

function foo() {
  console.log("foo");
}

function bar() {
  console.log("bar");
}

setTimeout(foo, 0);
bar();

 

  1. 전역 코드가 평가되어 전역 실행 컨텍스트가 생성되고 콜 스택에 푸시됩니다.

  2. 전역 코드가 실행되기 시작하여 setTimeout 함수가 호출됩니다. 이때 setTimeout 함수의 함수 실행 컨텍스트가 생성되고 콜 스택에 푸시되어 현재 실행중인 컨텍스트가 됩니다. 그리고 브라우저 또는 Node.js의 호스트 객체 타이머 함수도 함수이므로 함수 실행 컨텍스트를 생성합니다.

  3. setTimeout 함수가 실행되면 콜백 함수를 호출 스케줄링하고 종료되어 콜 스택에서 팝됩니다, 즉 타이머 설정과 타이머가 만료되면 콜백 함수를 테스크 큐에 푸시하는 것은 브라우저 또는 Node.js의 역할입니다.

  4. 브라우저 또는 Node.js가 설정한 타이머의 만료를 기다리면서 자바스크립트 엔진은 현재 실행 컨텍스트 스택에 있는 bar에 대한 실행 컨텍스트를 수행합니다.

  5. bar가 수행이 만료되어 실행 컨텍스트 스택이 비어있고 타이머 또한 만료되어 브라우저 또는 Node.js가 테스크 큐에 foo 함수가 enqueue된 상태라면은 이벤트 루프가 이를 확인하여 실행 컨텍스트 스택에 push합니다.

  6. 실행 컨텍스트 스택에 foo 실행 컨텍스트가 push되면 자바스크립트 엔진은 이를 확인하여 해당 실행 컨텍스트를 실행합니다.




'Programming Language > JavaScript' 카테고리의 다른 글

Javascript의 Promise란?  (0) 2022.12.19
JSON(Javascript Object Notation)이란?  (0) 2022.12.19
Set과 Map  (0) 2022.12.19
자바스크립트 Symbol이란?  (0) 2022.12.19
ES6에서의 함수  (0) 2022.12.19

+ Recent posts