
자바스크립트 엔진은 싱글 스레드입니다. 쉽게 말해서 콜 스택이 하나라는 뜻입니다. 그럼에도 불구하고 비동기 코드를 이용하면 코드가 막힘없이 동작합니다. 이것이 가능한 이유는 이벤트 루프 때문입니다.
자바스크립트의 비동기 코드는 처음부터 콜 스택으로 넘어가는 것이 아니라. 백그라운드 환경(웹이라면 웹 api)으로 넘어가서 바로 처리 가능한 상태로 만들어집니다. 처리가 가능한 코드는 콜백 큐로 넘어가서 실행되기 전까지 큐에서 대기를 하게 됩니다.
이때 이벤트 루프가(while loop) 콜 스택이 빌 때까지 코드들을 콜백 큐에서 대기시키다가 콜 스택이 전부 빈다면 그때부터 큐에 있던 코드들을 콜 스택으로 넘겨서 하나의 콜 스택에서 모든 함수들을 처리하게 됩니다. 병렬 처리(한 번에 여러 개의 코드 실행)가 아니라 외주를 줘서 실행 가능하게 만든 뒤애 한 곳에서 처리하는 개념입니다.

비동기 자바스크립트 코드는 이벤트 루프를 통해서 콜 스택에 들어가기 전에 microtask queue혹은 callback queue에 들어가게 됩니다 queue(줄)이라는 뜻처럼 먼저 들어온 것부터 실행됩니다. 같은 큐지만 microtask queue가 callback queue보다 먼저 실행됩니다. Promise코드는 microtask queue로 들어가게 됩니다.
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0);
Promise.resolve()
.then(function () {
console.log('promise1');
})
.then(function () {
console.log('promise2');
});
console.log('script end');
// script start
// script end
// promise1
// promise2
// setTimeout
실행해서 보면 같은 비동기 코드라도 Promise코드가 먼저 실행되는 것을 볼 수 있습니다.