프론트엔드/JavaScript

[JavaScript] 이벤트 루프(Event Loop)란?

zero2-pooh 2023. 9. 12. 21:18

이번 포스팅은 자바스크립트의 '이벤트 루프'에 대해 포스팅하려고 한다. 

이벤트 루프를 알아보기에 앞서 JavaScript의 특징부터 알아야 한다! 

 

JavaScript는 *싱글 스레드 언어라고 알려져 있다.

*싱글 쓰레드란?

- 여러 개의 작업이 있더라도 한 번에 하나의 작업만 수행할 수 있다.

 

❗️하지만 JavaScript를 사용해 보면 멀티 스레드처럼 동시에 여러 작업을 수행할 수 있다는 것을 알 수 있다.

그렇다면 JavaScript는 정말 싱글스레드 언어가 맞을까??😲

 

자세히 알아보자!


JavaScript는 정말 싱글 쓰레드 언어일까?

그렇다! 정확하게 말하면

👉🏻 자바스크립트의 메인 스레드인 이벤트 루프가 싱글 스레드이기 때문에 자바스크립트를 싱글 스레드 언어라고 부른다.

하지만 이벤트 루프만 독립적으로 실행되지 않고 웹 브라우저NodeJS 같은 멀티 스레드 환경에서 실행된다.

💡즉, 자바스크립트 자체는 싱글 스레드가 맞지만 자바스크립트 런타임은 싱글 쓰레드가 아니다.

싱글 스레드로 어떻게 한 번에 여러 요청을 처리할까?

기존 동기식 요청은 코드를 위에서부터 한 줄 한줄 차례대로 실행한다.

그래서 하나의 작업에 걸리는 시간에 관계없이 첫 번째 코드가 실행된 뒤 다음 코드가 실행된다.

 

이렇게 되면 앞의 작업시간이 길수록 시간 및 자원의 낭비가 심해진다.

하나의 요청이 완료될 때까지 기다리지 않고 동시에 다른 작업을 실행하는 =>  비동기 호출로 극복할 수 있다.👍🏻

 

❓그렇다면 자바스크립트는 싱글 스레드로 동작하며 어떻게 한 번에 여러 요청을 처리할까?

👉🏻 바로 비동기 작업을 통해 여러 요청들을 처리하게 된다. 그렇다면 비동기 작업은 어떻게 동작할까?

 


JavaScript의 비동기 런타임 과정

자바스크립트가 비동기 코드를 어떻게 동작시키는지 알아보기 위해선 일단 자바스크립트 런타임 환경에 대해 알아야 한다. 

자바스크립트가 실행될 때는 👇🏻아래와 같은 요소들이 실행을 도와준다.

  • Call Stack: 자바스크립트에서 수행해야 할 함수들을 순차적으로 스택에 담아 처리
  • Web API: 웹 브라우저에서 제공하는 API로 AJAX나 Timeout 등의 비동기 작업을 실행
  • Event Loop: Call Stack이 비어있다면 Task Queue의 작업을 Call Stack으로 옮김(Event Loop는 Call Stack이 비어있는지 항상 확인한다)
  • Callback Queue: Web API에서 넘겨받은 Callback함수를 저장. (콜 스택에 가기 위한 "대기열"이라고 생각하면 된다.)

❗️여기서 주의하셔야 할 점이 있다!

단순히 모든 비동기 코드가 이곳에 쌓이는 것은 아니다. Callback Queue에는 크게 세 가지 종류가 있다.

 

1. Task Queue 

- setTimeout, setInterval과 같은 코드다.

 

2. Microtask Queue

- Promise callback, async callback과 같은 코드다.

 

3. Animation Frames

- requestAnimationFrame과 같은 코드다.

 

👉🏻 "Microtask Queue > Animation Frame > Task Queue" 순으로 Microtask Queue가장 먼저 실행되고
Task Queue가장 늦게 실행된다.

 

 

 

👇🏻 아래와 같이 우선순위가 높은 큐가 비워져야만 다음 큐가 실행된다. Microtask Queue가 비면 Task Queue가 실행되는 것!


여기서부턴 자바스크립트의 이벤트 루프가 어떻게 작동하는지 gif로 간단하게 알아보자.

 

 

1. 제일 먼저console.log('Start!')가 출력된다. 

 

 

2.  setTimeout이 Web API로 이동한다. 

 

 

3. setTimeout의 콜백은 Task Queue로 이동하고 Promise의 then이 Microtask Queue로 이동

 

 

4. console.log('End!') 출력

 

 

5. Promise의 콜백이 콜스택에 들어가 res를 출력

 

 

6. Microtask Queue가 비어져 있으므로 Task Queue에 있는 setTimeout의 콜백에 콜스택으로 이동, Timeout! 출력


옛날 자바스크립트를 배울 때 이벤트 루프를 대략적으로만 알고 넘어갔는데,

이번 포스팅을 통해서 자바스크립트의 Event Loop에 대해 더 정확히 알게 되어 좋았다!

 

이 외에도 asyn await 도 있지만 그건 다음에 포스팅을 해보려고 한다. 

 

 

 

 

 

 

 

참고

https://chanyeong.com/blog/post/44

https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke#syntax

https://talkwithcode.tistory.com/89