자바스크립트는 싱글 스레드 기반 프로그래밍 언어입니다.
싱글 스레드란 한 번에 하나의 작업만 할 수 있음을 의미합니다.
따라서 하나의 작업이 오래 걸리면 다음 작업이 Blocking되어 suspend time이 늘어나게 됩니다.
이를 해결하기 위해 자바스크립트는 이벤트 루프를 사용하여 비동기 방식으로 Non-Blocking IO을 지원합니다.
Non-blocking I/O(Asynchronous I/O 혹은 Non-sequential I/O) : 입출력 처리는 시작만 해둔 채 완료되지 않은 상태에서 다른 처리 작업을 계속 진행할 수 있도록 멈추지 않고 입출력 처리를 기다리는 방법을 말한다.
JS엔진은 비동기 관련 작업을 할 수 가 없습니다.
이를 해결하기 위해 브라우저에서 지원하는 WebAPI 기능들을 사용하는데요.
바로 DOM API와 setTimeout, HTTP requests(AJAX)등이 있습니다.
Event Loop가 브라우저와 Call Stack 간의 중재 역할을 하면서 Async(비동기), Non-Blocking 동작을 수행하게 만들 수 있습니다.
먼저 자바스크립트 엔진부터 보겠습니다.
대표적으로 JS 엔진은 구글의 V8 엔진이 있습니다.
크롬과 노드 안에서 작동합니다.
자바스크립트 엔진은 다음과 같은 두 가지 구성 요소를 가집니다.
Memory Heap : 메모리 할당이 일어나는 곳
Heap : 구조화되지 않은 넓은 메모리 영역 -> 객체(변수, 함수등)들이 담긴다.
Call Stack : 실행될 코드의 한 줄 단위로 할당되어 실행
위 그림에서도 알 수 있지만 자바스크립트에는 이벤트 루프가 없습니다.
V8과 같은 자바스크립트 엔진은 단일 호출 스택을 사용하고, 요청이 들어오면 그 순서에 따라 순차적으로 처리할 뿐입니다.
그러면 비동기 요청은 어떻게 처리할까요?
자바스크립트 엔진을 구동하는 런타임 환경(브라우저나 Node.js)이 담당합니다.
위에서 말했듯이 JS가 비동기 처리를 위해 JS엔진과 브라우저 WebAPI를 함께 사용합니다.
아래 그림은 이를 이해하기 쉽게 표현한 것입니다.
Call Stack 은 프로그램 상에서 어떤 작업을 먼저 수행할지에 대한 스케줄링된 스택 자료구조입니다.
스택은 LIFO(Last In First Out)를 가진 자료구조입니다.
예를 들어 first함수가 호출되면 Call Stack에 쌓이고(push) 함수 실행이 완료되면 제거됩니다.(pop)
: 각 요청에 따른 비동기 처리를 기능을 지원합니다.
Queue(First In First Out) 자료구조이며, 비동기 처리가 끝난 후 실행되어야 할 콜백 함수가 차례로 할당됩니다.
callback queue
는 순서에 맞게 할당되는 콜백함수들 중에서 우선순위에 따른 처리를 합니다.
ex) Promise.then()이 setTimeout()보다 우선 처리됨
microtask queue > animation frames > task(event) queue
Call Stack이 비어있는 지 확인 후
Callback Queue에 할당된 콜백 함수를 순서에 맞춰 Call Stack에 할당해줍니다.
순서에 맞춰 할당해주지만 Callback Queue의 우선순위에 따라 순서가 달라질 수 있습니다.
동기 작업에 대한 예시입니다.
function multiply(x, y) {
return x * y;
}
function printSquare(x) {
var s = multiply(x, x);
console.log(s);
}
printSquare(5);
아래 그림은 비동기 작업에 대한 순서를 나타냅니다.
const foo = () => console.log('First');
const bar = () => setTimeout(() => console.log('Second'), 500);
const baz = () => console.log('Third');
bar();
foo();
baz();
reference
✨♻️ JavaScript Visualized: Event Loop
https://new93helloworld.tistory.com/358
움짤 잘만드셨네요 ㅎㅎ 단박에 이해하고 갑니다~