비동기 이벤트 루프
JavaScript 런타임 종류
자바스크립트는 프로그래밍 언어일 뿐, 자바스크립트를 실행하기 위한 환경이 필요합니다.
1. 웹 브라우저
물론 다양한 자바스크립트 엔진이 존재하나, 대표적으로는 크롬의 V8 엔진이 있습니다.
2. NodeJS
크롬의 V8 엔진을 활용해 브라우저 없이도 JS를 실행할 수 있도록 만든 런타임 환경입니다.
런타임 동작 방식
싱글 스레드 기반이지만, 이벤트 루프 기반의 비동기 처리 방식을 통해 높은 처리 성능을 보입니다.
싱글 스레드 & 실행 컨텍스트
JS는 싱글 스레드 기반이라 하나의 실행 흐름에서 코드가 실행됩니다. 즉, 한 번에 한 가지 일만 수행합니다. 하나의 콜 스택만을 사용하면서 요청들이 동기적으로 처리됩니다.
이때, 실행 컨텍스트라는 개념(객체) 안에서 코드가 관리됩니다.
실행 컨텍스트
자바스크립트 코드가 실행되면 실행 컨텍스트가 생성됩니다. 이후 코드들이 콜 스택(Call Stack)에 추가됩니다.
function first() {
// 2) second 호출 -> 콜 스택에 추가
// 5) second 완료 -> 콜 스택에서 제거
second();
}
function second() {
// 3) console.log 호출 -> 콜 스택에 추가
// 4) console.log 작업 완료 -> 콜 스택에서 제거
console.log("Hello");
}
// 1) first 호출 -> 콜 스택에 추가
// 6) first 완료 -> 콜 스택에서 제거
first();
JavaScript
복사
이처럼 콜 스택 자료구조에 쌓인 순서대로 코드를 실행
이벤트 루프 기반 비동기 처리
싱글 스레드라면, 하나의 작업이 끝난 후 다른 작업이 실행될 겁니다. 그러나, 자바스크립트는 시간이 오래 걸릴 수 있는 작업들을 비동기로 처리함으로써 동시에 다른 작업들이 요청이 완료될 때까지 기다렸다가 실행되지 않고 별개로 실행될 수 있도록 합니다.
이렇듯 비동기 작업(setTImeout, fetch, EventListener 등)들을 별도로 처리할 수 있도록 하는 핵심 요소가 이벤트 루프입니다.
이벤트 루프의 동작 방식
1.
콜 스택이 비어있는 지 확인
2.
콜 스택이 비었다면, TaskQueue나 MicrotaskQueue에 있는 작업을 실행
3.
윗 과정을 반복하면서 비동기 작업을 처리
// 1) 실행
console.log("Start");
// 2) WebAPI로 전송
setTimeout(() => {
// 4) 콜 스택이 빈 경우에 이벤트 루프가 setTimeout의 콜백을 태스크 큐에서 가져와 실행
console.log("Timeout");
}, 0);
// 3) 실행
console.log("End");
/* 결과
Start
End
Timeout
*/
JavaScript
복사
Task Queue & Microtask Queue
JS의 비동기 작업은 여러 가지가 있습니다. 여러 비동기 작업은 우선순위가 각기 다릅니다. 이를 마이크로태스크와 태스크로 구분합니다.
Microtask Queue
•
Promise.then(), MutationObserver , process.nextTick(), async functions 같은 작업이 들어갑니다.
•
콜 스택이 비면, 가장 먼저 실행됩니다.
Task Queue
•
setTimeout(), setInterval() , setImmediate() 등의 작업이 들어갑니다.
•
마이크로태스크 큐가 끝난 후 실행됩니다.
참고 자료
