브라우저에서만 작동하던 스크립트 언어인 자바스크립트를 서버 사이드에서도 작동할 수 있도록 해주는 비동기 이벤트 기반의 자바스크립트 런타임 환경
- 싱글 쓰레드 : Task를 처리하는 하나의 단위인 쓰레드가 하나 밖에 없어 메인 쓰레드 하나와 하나 밖에 없는 이벤트 루프를 가진다
- Non Blocking I/O : 싱글 쓰레드지만 이벤트 발생시 이미 기존의 이벤트를 처리하고 있어도 들어오는 이벤트를 막지 않는 Non-Blocking I/O의 성질을 띄고 있다. 이게 가능한 배경에는 복잡한 일들을 대신 처리해주는 Node.js의 libuv 라이브러리 내부에 위치한 C++ 쓰레드 풀 덕분이다
- 메모리를 할당하는 메모리힙과 코드가 호출되면서 컨텍스트를 스택으로 쌓는 콜스택만 존재하던 자바스크립트 엔진은 원래 동기 처리만 지원했으나,자바스크립트 런타임 환경인 브라우저나 Node.js가 생기면서 이들이 비동기 처리를 담당
- 엔진만 있으면 동기 처리지만, 엔진 외부에 위치한 런타임 환경으로 인해 비동기 처리가 가능해진다
Node.js와 브라우저(Chrome, etc) 둘 다 자바스크립트의 런타임 환경이며, 비동기 처리를 지원하지만 처리 방식엔 차이점이 존재한다
- 특정 이벤트 발생
- 해당 이벤트, 즉 함수의 컨텍스트 생성
- 콜스택에 해당 함수 컨텍스트를 넣기
- 동기처리 함수일 경우, 콜스택 최상단에서 Task가 수행되고 종료되면 콜스택에서 제거
- 비동기처리 함수일 경우, 콜스택에서 빠져 곧바로 비동기 처리를 도와주는 Web API로 이동
- Web API에서 비동기처리 함수의 Task가 끝나면, 해당 함수의 콜백함수를 콜백큐로 넣기
- 이벤트루프는 콜스택에 처리되는 컨텍스트가 있는지 계속 체크하고 비어있으면 콜백큐의 FIFO 성질에 따라 가장 앞에 있는 콜백함수를 차례대로 콜스택에 넣어 Task를 실행
- 특정 이벤트의 콜백함수가 콜스택에 넣어져 Task가 종료되면 이벤트 최종 종료
- 특정 이벤트(클라이언트의 HTTP Request) 발생
- 동기 이벤트일 경우 V8 Engine의 콜스택에 스택처럼 쌓아 처리하고 제거
- 비동기 이벤트일 경우 Node.js의 libuv에 위치한 싱글 스레드인 이벤트 루프가 해당 이벤트를 받아서 처리되기도 전에 OS 커널 또는 내부 C++ Thread Pool(멀티 스레드)로 할당
- 할당받은 이벤트 작업이 끝나면 콜백큐에 콜백 함수 전달
- 이벤트 루프는 V8 Engine의 콜스택이 빌 때마다 콜백큐의 콜백 함수들을 FIFO 방식대로 콜스택에 넘겨서 실행
- 콜스택에서 해당 이벤트 실행이 끝나면 제거
- 즉 Node.js 서버가 클라이언트에게 응답을 하며 이벤트 종료