Javascript

자바스크립트와 싱글스레드 그리고 비동기 처리 원리 2부

마손리 2022. 12. 7. 07:00

자자자!! 좀만 더 집중합시다!!

지난 시간 자바스크립트 V8 엔진의 메모리 구조와 데이터 처리방식에 이어서 이번 포스트의 핵심인 Event loop에 대해 알아보겠습니다. (지난 포스트: https://mason-lee.tistory.com/6)

 

Web API 동작 원리

먼저 코드를 실행시키면 크롬의 V8 엔진은 코드의 함수들이 호출될때 Stack에 올리게 됩니다.

하지만 이전 포스트 그리고 위의 그림을 보시면 setTimeout과 같은 WebAPI는 V8 엔진에 존재하지 않습니다.

이러한 WebAPI가 Stack에 올라오게되면 V8은 자바스크립트의 실행환경인 브라우저(여기에서는 크롬)로 WebAPI들을 넘겨준후 다음 함수들을 Stack에 쌓게되고 다음 함수들을 처리합니다. 

 

V8이 다른 함수들을 처리하는동안 브라우저는 넘겨받은 WebAPI들을 실행하고 실행이 완료가되면 콜백함수를 Callback queue로 넘기게 됩니다. 

 

이제야 Event loop가 할일이 생겼습니다. 이 Event loop는 Stack과 Callback queue를 계속해서 주시하는데 만약 Callback queue에 콜백 함수가 들어와있으면 Stack을 확인한후 Stack이 비어있다면 제일 처음 들어온 콜백함수를 V8의 Stack으로 넘겨 주게됩니다.

 

여기서 신기한 점은 V8의 Stack은 LIFO의 성질을 가진 반면 브라우저의 Callback queue는 FIFO의 성질을 가지고있습니다.(그냥... 신기하다고요...)

 

먼소리고???

저도 뭐라는건지 모르겠습니다... (영상을 몇번을 본후에야 이해했습니다... 힘내십시오...)

간단한 예제를 통해 설명해드리겠습니다.

console.log("Hello");
setTimeout(() => console.log("world"), 5000);
console.log("!!");

위의 코드를 자바스크립트로 작동시키면

위와 같은 처리가 이뤄집니다.

  1. console.log("Hello")가 스택에 옴겨지면서 실행 후 스택에서 제거된다
  2. 두번째 함수인 setTimeout()과 내장되있던 콜백함수가 스택에 올려지지만 V8은 브라우저로 보낸다
  3. 스택이 비워지면서 세번째 함수인 console.log("!!")를 스택에 올리며 실행후 스택에서 제거, 이제 스택은 비어지게됨
  4. 같은시간 브라우저는 setTimeout을 실행하고 실행이 완료되면 콜백함수인 console.log("world")를 Callback queue로 전달
  5. Event loop는 Callback queue에 콜백함수가 있는지 확인하고 스택이 비어있는지 확인 후 콜백함수를 스택으로 전달 그리고 실행

이러한 순서로 비동기화가 이뤄지게 됩니다.

 

정리

자바스크립트의 실행환경(브라우저)안의 V8 엔진에서는 함수들만 실행 (WebAPI들을 실행할 코드들은 브라우저에 내장되어 있음)

V8에서는 WebAPI들을 처리못하기때문에 브라우저로 보낸후 다음 함수들을 처리함

V8에서 다른 함수들을 처리하는 동안 브라우저는 받아온 WebAPI들을 실행 후 콜백함수를 Callback queue에 전달

Event loop가 V8의 활동이 끝낫는지 체크후 브라우저에 남아있는 콜백함수를 스택에 옴김 (여기서 동시성이 발생)

 

여기까지가 자바스크립트의 비동기처리 원리였습니다. 노드js의 경우 WebAPI 대신 C++ API를 사용할뿐 다르지 않다고 하는데 나중에 시간되면 한번 파헤처 보도록 하겠습니다.

 

(출처:https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=305s)

(이번포스트는 위의 동영상을 기반으로 만들어젔으며 자바스크립트의 싱글스레드를 공부하시는 분이라면 꼭 한번 시청하시는것을 추천드립니다!)