[JavaScript] 이벤트루프에 대하여

최예닮·2022년 12월 18일
0
post-thumbnail

내가 쓴 글중 Node 에 대해 정리한 글이 있다.

Node.js 에 대해 알아보자

여기에서 이벤트루프 라는 친구가 있는데 사실 내가 100프로 이해하지 못해 좀 더 자세히 공부를 해보았다.

어떤분의 블로그를 보고 공부하였는데 이해가 쏙쏙 되었다. 출처는 맨 아래에 남기겠다

자바스크립트는 비동기 로 동작하기 때문에 단일 스레드에도 불구하고 동시에 많은 작업을 수행한다고 한다.

하지만 자바스크립트 언어 자체가 비동기 동작 을 지원하는 것은 아니라고 한다.

비동기로 동작하는 핵심요소

자바스크립트 언어가 아닌 브라우저 가 가지고 있다. (Node에서는 libuv 라이브러리 등)

브라우저 의 구성은 ?

  • Web APIs
  • Event Table
  • Callback Queue
  • Event Loop
  • 🎸🏮🏮(기타등등) ...

그럼 이해를 돕기 위해 그림으로 표현하겠다.

  • Heap: 메모리 할당이 발생하는 곳
  • Call Stack : 실행된 코드의 환경을 저장하는 자료구조, 함수 호출 시 - Call Stack에 push 됨
  • Web APIs: DOM, AJAX, setTimeout 등 브라우저가 제공하는 API
  • Callback Queue, Event Loop, Event Table(그림엔 없음)
setTimeout(function exec() {
  console.log('second')
}, 1000);

⬆️ 코드가 어떤 역할을 하는지 살펴보자

  • Web APIs: setTimeout이 Call Stack에 들어와 실행되면 Browser API인 timer를 호출합니다.
  • Event Table: 특정 event(timeout, click, mouse move 등등)가 발생했을 때 어떤 callback 함수가 호출되야 하는지 를 알고 있는 자료구조입니다. 위 코드에서 호출된 timer가 종료되면 event가 발생하게 되는데 이때 exec callback 함수가 실행되어야 한다는 것을 Event Table 이 알고 있습니다.
  • Callback Queue: 이벤트 발생 시 실행해야 할 callback 함수가 Callback Queue에 추가됩니다.
  • Event Loop: Event Loop의 역할은 간단합니다.
    1) Call StackCallback Queue 를 감시합니다.
    2) Call Stack이 비어있을 경우, Callback queue에서 함수를 꺼내 Call Stack에 추가 합니다.

예제를 보면서 확인해보자

console.log('first')

setTimeout(function cb() {
    console.log('second')
}, 1000); // 0ms 뒤 실행

console.log('third')

위 코드 동작에 순서를 확인해보자

  1. console.log('first')Call Stack 에 추가가 되고

  2. console.log('first') 가 실행되어 브라우저 화면에 출력하고 Call Stack 에서 제거

  1. 그 다음 순서인 setTimeout(function cb() {..})Call Stack 에 추가된다.

  1. setTimeout 함수가 실행되면서 Browser가 제공하는 timer Web API 를 호출합니다. 그 후 Call Stack 에서 제거됨

  2. 그 다음순서인 console.log(‘third’)Call Stack추가됨

  3. console.log(‘third’) 가 실행되어 화면에 출력되고 Call Stack 에서 제거됨

  1. setTimeout 함수에 전달한 0ms 시간이 지난뒤 Callback 으로 전달한 cb 함수가 Callback Queue 으로 추가

  1. Event LoopCall Stack 이 비어있는 것을 확인하고 Callback Queue 를 살펴봅니다. cb 를 발견한 Event LoopCall Stackcb추가

  1. cb 함수가 실행 되고 내부의 console.log(‘second’)Call Stack추가됨

  1. console.log(‘second’) 가 화면에 출력되고 Call Stack 에서 제거됨

  1. cbCall Stack 에서 제거됨

와... 진짜 이렇게 흐름이 돌아가는구나... 위 예시를 보니까 자바스크립트브라우저 의 구성들이 어떻게 동작하는지 이해하게 되었다.

Event Loop 는 ?

Call Stack 이 비어있을 경우 Callback queue 에서 함수를 꺼내 Call Stack 에 추가 하는 것 !

또 다른 예제를 봐보자

console.log('first');
setTimeout(
    function cb() { 
        console.log('second'); 
    }
, 0);
wait3Seconds();
console.log('third');

  
function wait3Seconds() {
    let start = Date.now(), now = start;
    while (now - start < 3 * 1000) {
        now = Date.now();
    }
}

console.log 결과 어떻게 나올까용 ~?

(나는 wait3Seconds 가 3초를 기다리니까 이거는 진짜 솔직히 first -> second -> third 순으로 갈줄 알았다...)

결과는

first
third
second

....

wait3Seconds 함수가 실행된 후 3초 동안 Call StackEvent Loop 상태를 그림으로 확인해보자

?!! 와씨 🤦‍♂️

setTimeout 이 호출되고 0ms 뒤에 callback 으로 전달 된 cb 는 이미 Callback Queue 안에 있다. 근데 왜 secondthird 보다 뒤에 출력이 될까 ?

-> Call stackwait3Seconds 함수가 있기 때문이다.

내가 위에 적은 Event Loop 기억하는가?

Event LoopCall Stack 이 비어있지 않기 때문에 Callback Queue 를 확인하지 않는다. 그러니까 wait3Seconds 함수 종료 후에 cosole.log('third')Call Stack 에 추가되어 먼저 출력이 되는 것이다.

1. setTimeout 의 delay 인자가 delay ms 후에 실행되는 것을 보장하지 않는다.
-> 즉, delay ms 후에 Callback Queue 에 들어가는 것을 보장한다.

그러니까, 나는 자바스크립트 언어가 비동기 특성을 제공하는 줄 알았는데 그게 아니라

브라우저 의 구성 요소들이 비동기를 제공하는 것 이었다.

자, 그럼 오늘 한걸 엑기스 로 정리해보겠다.

(후.. 힘들게 공부했지만 공유해드림 ㅎ.ㅎ)

1. Event Loop

  • Call Stack 이 비어있을 경우 Callback Queue 에서 함수를 꺼내 Call Stack 에 추가 하는 것 !
  • 즉, Call Stack 에 함수가 있다면 Callback Queue 동작 안한다 !

2. 자바스크립트 = 단일 스레드 지만, 비동기로 동작 하기에 동시에 많은 작업 수행 가능 BUT!

💡 자바스크립트 언어 자체가 비동기 동작 을 지원하는게 아니라 브라우저 의 구성요소들이 제공하는 것이다 !

솔직히 오늘 공부 재미있었음, 좀 맛있었다 🍽


출처: JavaScript 비동기 핵심 Event Loop 정리

profile
산을 오르려고 하는데 이제 주차장에 막 주차한 초보개발자

0개의 댓글