Javascript를 브라우저 외부에서 실행가능하도록 하는 JS 런타임 환경
기존에는 브라우저에서만 동작하여 클라이언트 측 언어였으나 NODEJS 출현 이후 서버에서도 활용된다.
코드 실행 환경. 즉, 코드를 실행하기 위한 일련의 구성요소와 도구를 의미한다.
크롬 브라우저는 V8 엔진, DOM, Web Apis 등으로 런타임 환경이 구성된다.
NODEJS는 V8엔진, libUV, Nodejs core lib 등으로 런타임 환경이 구성된다.
NodeJs는 위와 같은 3가지 특징을 가지는데 위 3가지 특징은 연관성을 가진다.
이를 한 줄로 요약하면 다음과 같다.
NodeJs는 싱글스레드 기반으로, 비동기 I/O와 이벤트 루프를 통해 논블로킹 처리를 지원하는 런타임 환경이다.
싱글스레드는 단 하나의 콜스택을 가진다. 즉, 한번에 하나의 일을 처리할 수 있다.
싱글스레드인데 어떻게 비동기적으로 I/O를 처리하는지 의문이 든다.
V8 엔진이 Js 런타임 환경을 제공한다.
블로킹은 느린 작업을 의미한다.
콜스택에 느린 작업이 포함된 경우 블로킹이라 말할 수 있다.
만약 동기적으로 작업한다면 블로킹 코드가 있는 경우 매우 느리게 작업을 수행할 것이다.
console.log("HI")
setTimeout(()=>{console.log("LONG")},10000)
console.log("HELLO")
위 코드를 동기적으로 실행하게 된다면 다음과 같이 출력된다.
HI
(10초 뒤)
LONG
HELLO
하지만 위 코드를 크롬에서 돌리게 되면 다음과 같다.
HI
HELLO
(10초 뒤)
LONG
보통 싱글스레드라고 한다면 아래 그림처럼 생각할 수 있다.

브라우저가 그림과 같다면 위에서 보았던 첫번째 결과처럼 동작할 것이다.
하지만 실제 브라우저는 두번째 결과를 보인다.
그렇다면 실제 브라우저는 어떻게 동작할까?

단순히 콜스택과 힙만 있던 구조에서 뭔가가 추가되었다. 딱봐도 중요해보이는 친구들이다.
Web APIs , Queue, EventLoop 이 3가지 덕분에 브라우저는 블로킹 코드들을 논 블로킹하게 처리할 수 있게되었다.
세 친구들이 어떻게 동작하는지 알아보자
우선 Web APIs는 setTimeout 같은 타이머의 시간초를 대신 세어주는 친구를 가지고 있다. 그래서 callstack에 들어온 setTimeout의 작업을 Web API에게 떠넘길 수 있다.
Web API는 시간을 세고있다가 정해진 시간이 되면 가지고 있던 callback 함수를 queue에 넣는다.
EventLoop는 Queue에 존재하는 작업을 Callstack에 집어넣는 역할을 수행하는데 Callstack이 비어있을 경우 작업을 집어넣는다.
Loop라는 말처럼 계속 돌면서 Callstack과 Queue의 상태를 살핀다.
https://developer.mozilla.org/en-US/docs/Web/API
WebAPIs를 찾아볼 수 있다.
하지만 Timer API는 찾아볼 수 없는데 setTimeout이나 setInterval같은 함수들은 Web Workers API가 하는 기능에서 찾아볼 수 있다.
위의 그림에서는 큐 하나로 표현했지만 실제 브라우저에서는 3개의 큐를 가지고 있다.
Task Queue , MicroTask Queue , Render Queue를 가지고 있다.
큐마다 하는 일이 달라서 '큐를 3개로 나누어 놓았겠구나' 라는 생각이든다.
각각의 큐는 어떤 일들을 처리하고 큐 간의 우선순위는 어떻게 나뉘어질까?
then catch의 콜백함수 들이 들어간다.queueMicrotask()의 콜백함수 Repaint 또는 Reflow를 처리할 때 사용되는 큐이다.우선순위
Microtask Queue > Task Queue > Render Queue
앞서서 브라우저에서 JS가 동작하는 방식을 보았다.
브라우저에서는 WebAPIs, 큐, 이벤트 루프를 통해서 논블로킹 비동기 처리를 지원할 수 있었다.
NodeJs도 브라우저와 유사한 방법으로 동작한다.
브라우저 환경이 아니기 때문에 WebAPI가 없는 대신 libuv를 활용해서 이를 지원한다.
libuv 내부에 이벤트 루프를 가지고 있어 비동기 작업, 네트워크 I/O와 같은 작업들이 이벤트 루프에 의해 처리된다.
하지만 브라우저의 이벤트 루프와는 약간은 다른 점이 libuv의 이벤트 루프는 6 단계를 거친다.

[출처] https://www.korecmblog.com/blog/node-js-event-loop
6단계의 페이즈 별로 어떻게 동작하는 지
https://www.korecmblog.com/blog/node-js-event-loop 블로그에 상세하게 나와있으니 참고하시길...
[참고자료]
https://www.youtube.com/watch?v=P9csgxBgaZ8
https://sjh836.tistory.com/149
https://www.korecmblog.com/blog/node-js-event-loop
https://blog.naver.com/pjt3591oo/221976414901
https://www.youtube.com/watch?v=8aGhZQkoFbQ
https://www.youtube.com/watch?v=cCOL7MC4Pl0
https://developer.mozilla.org/en-US/docs/Web/API
https://www.youtube.com/watch?v=eiC58R16hb8
https://javascript.plainenglish.io/how-the-event-loop-works-in-the-chrome-browser-ccf99c6c5a5