← 질문 목록
#19깊이 0
setTimeout(0)이 즉시 실행되지 않는 이유는?
콜백이 큐에 들어갈 뿐이고, 지금 돌고 있는 코드가 끝나야 이벤트 루프가 그것을 꺼내기 때문이다. 0은 "지금"이 아니라 "가능한 가장 이른 다음 차례"라는 뜻이다. 게다가 꺼내 가는 큐가 하나도 아니다.
- 지금 도는 동기 코드이게 끝나야 아래로 내려간다
- 마이크로태스크 큐Promise.then. 비워질 때까지 전부
- 매크로태스크 큐setTimeout, 이벤트 콜백. 한 번에 하나
자바스크립트는 한 번에 하나의 콜스택만 돌린다. 루프는 스택이 빌 때까지 아무것도 꺼내지 않는다. 앞선 동기 코드가 100밀리초를 쓰면 setTimeout(0)도 그만큼 밀린다.
마이크로태스크 큐는 매크로태스크보다 먼저, 그리고 스택이 빌 때마다 전부 비워진다. 그래서 나중에 등록한 Promise.then이 먼저 등록한 setTimeout(0)보다 앞선다.
핵심 정리
브라우저는 여기에 하한을 하나 더 얹는다. 중첩이 일정 단계를 넘으면 0을 요청해도 최소 지연이 걸린다. 재귀적으로 setTimeout(0)을 걸어 바쁘게 도는 코드를 막기 위한 장치다.
이 구조가 사용자에게 드러나는 때는 화면이 멈출 때다. 무거운 계산이 한 덩어리로 돌면 그동안 렌더링도 입력도 처리되지 않는다. 작업을 잘라 큐에 나눠 넣으면 사이사이에 화면이 숨을 쉰다 — setTimeout(0)의 쓸모가 대부분 여기에 있다.