이벤트 루프

Event loop

호출 스택이 비면 마이크로태스크를 먼저 처리하고, 그다음 태스크 큐의 작업을 실행합니다.

···
html
<div class="demo"><div class="head"><strong>EVENT LOOP</strong><span id="out">output: —</span></div><div class="scene"><div class="lane chip" id="stack">STACK<br><b>sync</b></div><span class="arrow">→</span><div class="lane chip" id="micro">MICROTASK<br><b>Promise</b></div><span class="arrow">→</span><div class="lane chip" id="task">TASK<br><b>timer</b></div></div><div class="foot"><span>sync → Promise → timer</span><span>tap to step</span></div></div>
css
.demo{width:min(92vw,660px);height:min(86vh,310px);border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:clamp(10px,2.5vmin,20px);display:flex;flex-direction:column;gap:clamp(6px,1.7vmin,12px);box-shadow:0 10px 35px rgba(0,0,0,.07);font:500 clamp(10px,2.8vmin,15px)/1.35 ui-monospace,SFMono-Regular,Consolas,monospace}
.head,.foot{display:flex;align-items:center;justify-content:space-between;gap:8px}.head strong{color:var(--accent);font-size:1.05em}.foot{color:var(--muted);font-size:.85em;min-height:1.4em}.scene{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center;gap:clamp(5px,1.5vmin,12px)}.chip{border:1px solid var(--line);background:var(--bg);border-radius:7px;padding:.4em .6em;text-align:center}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 12%,var(--surface))!important;color:var(--accent)!important}.dim{opacity:.42}.arrow{color:var(--muted)}
.lane{width:28%;height:55%;min-height:48px;display:flex;flex-direction:column;justify-content:center;gap:.5em}.lane b{font-size:1.08em}.arrow{font-size:1.3em}
js
const ids=["stack","micro","task"],names=["sync","Promise","timer"];let step=0;function advance(){ids.forEach((id,i)=>document.getElementById(id).classList.toggle("on",i===step));document.getElementById("out").textContent="output: "+names.slice(0,step+1).join(" · ");step=(step+1)%3}advance();const timer=setInterval(advance,900);document.querySelector(".demo").addEventListener("pointerdown",()=>{clearInterval(timer);advance()})

JavaScript는 동기 코드를 호출 스택에서 실행합니다. Promise 후속 작업은 마이크로태스크 큐에, 타이머 콜백은 태스크 큐에 들어갑니다. 스택이 비면 마이크로태스크를 먼저 모두 처리합니다.

데모는 동기 코드, Promise 콜백, 타이머 콜백을 순서대로 이동시킵니다. 타이머가 0ms로 예약돼도 현재 스택과 마이크로태스크보다 앞서 실행되지 않습니다.

언제 쓰나

Promise와 타이머의 출력 순서를 예측하거나 UI가 긴 동기 작업 때문에 멈추는 이유를 찾을 때 사용합니다.

페이지로 열기 ↗