자바스크립트는 싱글 스레드 기반의 언어이며, 자바스크립트 엔진은 하나의 호출 스택을 사용한다. 이는 요청이 동기적으로 처리되고 한 번에 한 가지 일만 처리가 가능하다는 것을 말한다.
하지만 자바스크립트 구동 환경(브라우저, Node.js)은 여러 스레드를 사용하는데 여러 스레드를 사용하는 자바스크립트 구동 환경과 하나의 스레드를 사용하는 자바스크립트 엔진과 연동되기 위해서 이벤트 루프가 필요하다.
자바스크립트 엔진
Web API
태스크 큐
이벤트 루프
태스크 큐는 마이크로 태스크 큐와 매크로 태스크 큐로 구분된다. 이 두 태스크의 차이는 처리할 작업의 우선순위이며 마이크로 태스크가 매크로 태스크보다 우선순위가 높다.
마이크로, 매크로 태스크에 속하는 작업들이다.
아래 예제를 통해서 동작 순서를 확인해보자.
// 코드 실행
console.log('콜 스택');
setTimeout(() => console.log('매크로 태스크'), 0);
Promise.resolve().then(() => console.log('마이크로 태스크'));
// 코드 실행 결과
콜 스택
마이크로 태스크
매크로 태스크
코드 실행 결과를 통해서 마이크로 태스크가 매크로 태스크보다 우선순위가 높은 것을 확인할 수 있다.
이벤트 루프는 아래의 과정을 반복한다.
이벤트 루프의 동작 방식을 이해한걸 바탕으로 아래 예제가 어떤 순서로 동작하는지 자세히 알아보자.
// 코드 실행
console.log('시작');
setTimeout(()=> console.log('타이머')); // (A)
Promise.resolve()
.then(()=> console.log('프로미스 1')) // (B)
.then(()=> console.log('프로미스 2')); // (C)
console.log('끝'); // (D)
// 코드 실행 결과
시작
끝
프로미스 1
프로미스 2
타이머
‘시작’ 출력
‘끝’ 출력
‘프로미스 1’ 출력
‘프로미스 2’ 출력
‘타이머’ 출력