Javascript 비동기 Event Loop 정리

jaejin·2023년 4월 16일

그냥 개념정리할려고 정리하는 글.

  • 비동기로 동작하는 핵심요소는 자바스크립트 언어가 아니라 브라우저가 가지고 있다.

Heap: 메모리 할당이 발생하는 곳

Call Stack: 실행된 코드의 환경을 저장하는 자료구조, 함수 호출 시 Call Stack에 push된다.

Web APIs: DOM, AJAX, setTimeout 등 브라우저가 제공하는 API

Callback Queue: Task Queue, Macrotask Queue라고도 부른다.

Web API가 수행한 비동기 함수를 넘겨받아 Event Loop가 해당 함수를 Call Stack에 넘겨줄 때까지 비동기 함수들을 쌓아놓는 곳이다.

이벤트 발생 시 실행해야 할 callback 함수가 추가되서 Callback Queue라고 부른다.

Event Table: 특정 event가 발상했을 때 어떤 callback 함수가 호출되야 하는지를 알고 있는 자료구조

Event Loop: 아래 두가지 역할을 함

  1. Call StackCallback Queue를 감시한다.
  2. Call Stack이 비어있는 경우, Callback queue에서 함수를 꺼내 Call Stack에 추가한다.

예시

setTimeout(function exec() {
  console.log('second')
}, 1000);

위 코드가 실행된다고 했을 때 각 구송요소의 역할을 예로 들면,

Web APIs: setTimeout이 Call Stack에 들어와 실행되면 Browser API인 timer를 호출한다.

Event Table: 위 코드에서 호출된 timer가 종료되면 event가 발생하는데, 이때 exec callback 함수가 실행되어야 한다는 것을 Event Table이 알고있다.

Callback Quque: exec callback 함수가 추가되는 곳

Job Queue(microtask queue)

ES6/ES2015에서 소개된 Job QueuePromise를 사용할 경우 사용된다.

  • Job Queue의 우선순위가 Callback Queue보다 높다.
  • Event Loop는 Call Stack이 비어있을 경우, Job Queue에서 기다리는 모든 작업을 처리하고 Callback Queue로 이동하게 된다.
console.log('fisrt');

setTimeout(function() {
   console.log('setTimeout - second');
}, 0);

var promise = new Promise(function(resolve, reject) {
   resolve();

});
promise.then(function(resolve) {
   console.log('promise - third');
})
.then(function(resolve) {
   console.log('promise - four');
});

console.log('five');

위의 우선순위에 따라 실행결과는 아래와 같이 출력된다.

fisrt
five
promise - third
promise - four
setTimeout - second

Animation Frames

개념을 정리하다가 추가로 찾은 개념으로 requestAnimationFrame와 같이 브라우저 렌더링과 관련된 task를 넘겨받는 Queue이다.

우선순위는 Microtask보다 낮고, MacroTask보다는 높다.

// 1. 실행
console.log("script start");

// 2. task queue로 전달
setTimeout(function () {
  // 10. task 실행
  console.log("setTimeout");
}, 0);

//3. microtask queue로 전달
Promise.resolve()
  .then(function () {
    // 6. microtask 실행
    console.log("promise1");
  }) // 7. microtask queue로 전달
  .then(function () {
    // 8. microtask 실행
    console.log("promise2");
  });

//4. AnimationFrame으로 전달
requestAnimationFrame(function () {
  //9. animation frame 실행
  console.log("animation");
});

//5. 실행
console.log("script end");

우선순위에 따라 결과는 아래와 같다.

script start
script end
promise1
promise2
animation
setTimeout

정리

Event Loop가 비동기 작업을 처리하는 우선순위는 Microtask Queue > Animation Frames > Task Queue

Event LoopMicrotask QueueAnimation Frames를 방문할 때는 큐 안에 있는 모든 작업을 수행하고, Task Queue를 방문할 때는 한번에 하나의 작업만 Call Stack으로 전달하고 다른 Queue들을 순회한다.

참조
https://velog.io/@titu/JavaScript-Task-Queue말고-다른-큐가-더-있다고-MicroTask-Queue-Animation-Frames-Render-Queue
https://medium.com/sjk5766/javascript-비동기-핵심-event-loop-정리-422eb29231a8

profile
jjlabsio

0개의 댓글