ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이벤트 루프 (콜 스택과 힙, 콜백 큐)
    JavaScript 2023. 4. 3. 22:18

    JavaScript는 단일 스레드 기반 언어로, JavaScript 엔진이 단일 콜 스택을 갖는다.

    비동기 요청은 어떻게 진행될까??

    비동기 요청은 JavaScript 실행 환경인 브라우저, Node.js가 담당한다.

    이 때 JavaScript 엔진과 실행 환경을 상호 연동시켜주는 장치가 Event Loop이다.

    따라서 Event Loop는 JavaScript 엔진에 있지 않고 그 환경에 속한다.

    (한번에 하나의 함수만 처리할 수 있지만 이벤트 루프에 기반한 동시성 모델을 지원한다.)

     

    Call Stack, Callback Queue의 상태를 체크하며 Call Stack이 빈 상태가 되면 Callback Queue의 첫 번째 콜백 함수를 Call Stack에 넣는다. 이러한 행위를 반복해 루프라고 한다. 또한, 이렇게 반복적인 행동은 틱이라고 부른다.

     

    Call Stack & Heap

    JavaScript엔진이 JavaScript를 실행할 때, 원시 타입 및 참조 타입을 저장하는 메모리 구조로 Call Stack과 Heap을 가진다.

    • Call Stack : 원시타입 값(기본형 데이터)과 함수 호출의 실행 컨텍스트를 저장하는 곳.
    • Heap : 객체, 배열, 함수와 같이 크기가 동적으로 변할 수 있는 참조타입 값을 저장하는 곳.
    • 동작 원리
      1. 전역 실행 컨텍스트가 생성되고 원시값은 Call Stack에, 참조값은 Heap에 저장된다.
      2. 함수가 실행되면 새로운 함수 실행 컨텍스트가 생성되며, 동일하게 원시값은 Call Stack, 참조값은 Heap에 저장된다.
      3. 함수 실행이 끝나면 함수 실행 컨텍스트는 Call Stack에서 제거된다.
      4. 전체 코드의 실행이 끝나고 전역 실행 컨텍스트가 Call Stack에서 제거된다. 전역 실행 컨텍스트가 제거됨에 따라 Heap의 객체를 참조하는 스택의 값이 없어 가비지 컬렉터에 의해 제거된다. 

     

    비동기 과정

    1. JavaScript 코드가 실행되고 함수가 호출되면, 호출된 함수는 Call Stack에 쌓인다.
    2. Stack의 후입선출 룰에 따라 제일 마지막에 들어온 함수가 먼저 실행되며, 실행된 함수는 Call Stack에서 제거된다.
    3. Stack에 쌓인 함수가 모두 실행된다.
    4. setTimeout같은 비동기 함수가 실행된다면, Web API가 호출되고 Call Stack에서 제거된다.
    5. 타이머가 종료되면 setTimeout의 콜백 함수를 Callback Queue에 넣는다.
    6. 이벤트 루프는 Call Stack이 빈 상태가 되면 Callback Queue에 있는 첫 번째 콜백을 Call Stack으로 이동시킨다.

     

    Callback Queue

    JavaScript의 실행 환경은 두가지 큐를 가지고 있다. 각각 스크립트 실행, 이벤트 핸들러, 콜백 함수 등의 테스크가 담기는 공간이다.

    이벤트 루프는 두개의 큐를 감시하다가 콜 스택이 비어있으면 콜백 함수를 꺼내 실행한다. 이때 Microtask Queue를 우선적으로 확인한다. 만약 Microtask Queue에 콜백이 있다면, 이를 먼저 Call Stack에 담는다. Microtask Queue에 처리할 콜백 함수가 없다면 Task Queue에 확인 후 처리한다.

    • Task Queue : setTimeout(), setInterval(), UI렌더링, requestAnimationFrame()이 담긴다.
    • Microtask Queue : Promise(then), MutaionObserver가 담긴다.

    댓글

heeezzang Tistory.