이벤트 루프에 대해 알아보자

date
Jul 16, 2022
thumbnail
slug
이벤트루프
author
status
Published
tags
JavaScript
Chrome
summary
이벤트 루프에 빠졌다..
type
Post
updatedAt
Jan 23, 2023 06:41 PM
일단 먼저 이벤트 루프를 알기전에 브라우저의 구성요소와 각 역할들을 알아야한다.
 
notion image

브라우저 구성요소

브라우저의 구성요소는 여러가지가 있지만, 대표적으로
  • JS Engine(Memory heap, Call Stack)
  • Web API
  • Callback Queue
  • Event Loop
4가지가 있다.

JS Engine

먼저 자바스크립트 엔진은 Memory HeapCallStack으로 구성되어있다. 가장 유명한 엔진에 구글의 V8엔진이 있다.
자바스크립트는 단일 스레드 프로그래밍 언어인데, 이는 자바스크립트는 Call Stack이 하나라는 특징을 이야기해준다.
  • Memory Heap : 메모리 할당이 일어나는 곳 (코드를 작성할 때 변수나 함수를 선언할때 이공간에서 할당됨.)
  • Call Stack : 코드가 실행될 때 쌓이는 곳, stack 형태로 쌓임

Web API

Web API는 자바스크립트 엔진이 아니다. Web API는 브라우저에서 제공하는 API로, DOM, Ajax, Timeout 등이 있다. Call Stack에서 실행된 비동기 함수는 Web API를 호출하고 Web API는 콜백함수를 Callback Queue에 넣는다.

Callback Queue

비동기적으로 실행된 콜백함수가 보관되는 영역이다.
콜백함수 ex) (1) setTimeout에서 타이머 환료후 실행되는 함수 (2) addEventListenner에서 click 이벤트가 발생했을 때 실행되는 함수들이 보관됨.

Event Loop

Event Loop는 call stack과 callback queue의 상태를 채크하며 , Call Stack이 빈 상태가 되면, Callback Queue의 첫번째 콜백을 CallStack에 넣는다. 이 행동을 반복하는데, 이 행동을 틱(tick)이라고 한다.

흐름 정리

  1. V8에서 코드가 실행되면 함수들은 Call Stack에 쌓인다.
  1. Call Stack은 말 그대로 stack이므로 마지막에 들어온 함수가 제일 먼저 실행된다
    1. 만약 비동기 함수가 실행되면, Web API가 호출된다.
    2. Webp API는 비동기 함수의 콜백함수를 Callback Queue에 넣는다.
    3. Event Loop는 여기서 Call Stack과 Callback Queue 이 둘을 확인하면서 Call Stack이 비었다면 Callback Queue의 첫번째 콜백함수를 Call Stack에 넣는다.
하지만 여기서 끝이 아니다.

Microtask Queue

Microtask Queue를 알아보기 전에 먼저 코드부터 보겠다.
console.log("안녕")

setTimeout(()=>console.log("셋타임아웃"), 0)

Promise.resolve().then(()=>console.log("프로미스")).then(()=>console.log("프로미스2"))

console.log("안녕 끝")
위 코드를 실행시키면 어떤 순서로 출력될까?
안녕
안녕끝
프로미스
프로미스2
셋타임아웃
이 순으로 출력된다. 왜 프로미스 → 셋타임 아웃 순으로 출력될까? 여기서 Microtask Queue의 개념이 나온다.
Event Loop는 먼저 Microtask Queue를 확인한다. 먼저 확인하고 Microtask Queue에 콜백이 있다면 Microtask Queue의 콜백을 먼저 Call Stack에 넣는다. 그리고 Microtast Queue에 콜백이 없다면 Task Queue에 확인 후 틱(tick)을 진행한다.
여기서 Promise의 then()은 콜백은 Task Queue가 아닌 Microtask Queue에 담긴다. 따라서 우선순위가 놓은 Microtask Queue부터 처리돼서 Promise의 콘솔이 먼저찍히고, setTimeout의 콘솔이 찍힌 것이다. (setTimeOut은 타이머 완료 후 콜백이 Task Queue에 담긴다.)

Animation Frames

자바스크립트 내장 API중 requestAnimationFrame API라는 것이 있는데, 이 함수가 실행되면 콜백이 Animation Frames에 담긴다. 그러면 Animation Frames는 우선순위가 어떻게 될까?
console.log("안녕")

setTimeout(()=>console.log("셋타임아웃"), 0)

Promise.resolve().then(()=>console.log("프로미스 1")).then(()=>console.log("프로미스 2"))

requestAnimationFrame(()=>console.log("리퀘스트애니메이션프레임"))

console.log("안녕 끝");
여기서 코드를 실행시키면
안녕
안녕끝
프로미스1
프로미스2
리퀘스트애니메이션프레임
셋타임아웃

우선순위

Microtask Queue > Animation Frames > Task Queue 순으로 실행되는 것을 알 수 있다.