let i = 0;
setTimeout(function () {
// (A)
console.log(i++, 'A');
}, 0);
Promise.resolve()
.then(function () {
// (B)
console.log(i++, 'B');
})
.then(function () {
// (C)
console.log(i++, 'C');
});
// 0 'B'
// 1 'C'
// 2 'A' 순으로 출력
위 코드는 B → C → A 순서로 실행된다.
분명 셋다 비동기 동작이라서, 태스크 큐에 순차적으로 들어가서 콜 스택으로 차례 대로 빠져나와서 실행되었을 것이다.
근데 왜 A → B → C 순서로 동작하지 않았을까?
그 이유는 Promise는 마이크로 태스크를 사용하기 때문이다. (ES6부터 도입)
setTimeout()은 콜백 A를 태스크 큐에 추가하는데,
Promise의 then() 메소드는 태스크 큐가 아니고 별도의 마이크로 태스크 큐에 추가한다.
위의 코드 실행이 끝나면, 태스크 이벤트 루프는 일반 태스크 큐 대신, 마이크로 태스크 큐가 비었는지 확인하고, 마이크로 태스크 큐에 있는 콜백 B를 수행한다. 콜백 B가 끝나면 마이크로 태스크 큐에 콜백 C가 들어오게 되고, 이벤트 루프는 마이크로 태스크 큐에 있는 콜백 C를 수행한다.
그 후에, 마이크로 태스크 큐가 빈것을 확인하고, 일반 태스크 큐에서 pop하여 나머지 동작을 수행한다.
아래 예제도 풀어보자
let i = 0;
const promise_1st = new Promise((res, rej) => {
console.log(i++,'A');
res();
});
console.log(i++,'B');
setTimeout(() => console.log(i++,'C'), 0);
const promise_2nd = promise_1st.then((val) => {
console.log(i++,'D');
});
setTimeout(() => console.log(i++,'E'));
const promise_3rd = promise_2nd.then((val) => {
console.log(i++,'F');
});
console.log(i++,'G');
// A -> B -> G -> D -> F -> C -> E
'개발 > FrontEnd Interview' 카테고리의 다른 글
Promise.all, Promise.race 차이는? (0) | 2021.04.09 |
---|---|
Promise란 무엇이고, 왜 등장하게 되었는가 (0) | 2021.04.09 |
IIFE와 클로저 (수정중) (0) | 2021.04.08 |
함수형 프로그래밍? 순수 함수? (0) | 2021.04.06 |
명령형? 선언형? 프로그래밍 방식 (4) | 2021.04.06 |