LogoSEO Jing
  • All Posts
  • SEO Jing
  • okayJing
  • KD Team
  • CLAB Coreteam
  • Study

Contact Me

© 2026 SEOJing. All rights reserved.

자바스크립트 퀴즈북 리마인드 Day 8: 이벤트 루프와 Promise 타이밍

2026년 7월 3일·3분 읽기
오늘의 질문: “setTimeout(..., 0)은 정말 바로 실행될까?”

먼저 맞혀보기

js
console.log("A");

setTimeout(() => {
  console.log("B");
}, 0);

Promise.resolve()
  .then(() => {
    console.log("C");
  })
  .then(() => {
    console.log("D");
  });

console.log("E");

출력은 A E C D B입니다. setTimeout(..., 0)이 “0초 뒤 즉시 실행”이라는 뜻으로 보이면 B를 너무 앞에 놓기 쉽습니다. 실제로는 현재 동기 코드가 끝나고, 마이크로태스크 큐가 먼저 비워진 뒤, 다음 태스크에서 timeout 콜백이 실행됩니다.

틀리기 쉬운 직감

비동기 코드를 “시간이 짧은 순서대로 실행된다”고 생각하면 Promise와 timer가 섞인 버그를 잘못 읽습니다. 브라우저와 Node 런타임은 실행 순서를 단순한 시간표가 아니라 스택이 비는 시점과 큐의 우선순위로 정합니다.

이벤트 루프와 마이크로태스크 실행 순서

최소 모델: 스택이 먼저, 그다음 microtask

리뷰할 때는 이 정도만 기억해도 대부분의 순서를 설명할 수 있습니다.

지금 실행 중인 동기 코드는 call stack에서 끝까지 돈다. 스택이 비면 microtask queue를 비운다. microtask 안에서 새 microtask가 생기면 그것도 같은 턴에 이어서 돈다. 그 뒤 렌더 기회가 오고, 다음 task가 하나 실행된다. 다음 task가 끝나면 다시 microtask를 비운다.

그래서 Promise.then, queueMicrotask, await 뒤쪽 코드는 보통 setTimeout보다 먼저 보입니다.

js
setTimeout(() => console.log("task"), 0);
queueMicrotask(() => console.log("microtask"));
console.log("sync");

// sync
// microtask
// task

async/await도 Promise 타이밍이다

await가 있으면 함수가 잠깐 멈추는 것처럼 보입니다. 하지만 “스레드가 멈춘다”보다 “나머지 부분이 Promise continuation으로 예약된다”에 가깝게 보는 편이 안전합니다.

js
async function run() {
  console.log("1");
  await null;
  console.log("2");
}

run();
console.log("3");

// 1
// 3
// 2

await null은 즉시 끝나는 값처럼 보여도, console.log("2")는 현재 동기 흐름 뒤로 밀립니다. UI 코드에서 await 뒤에 상태를 쓰는 부분은 “이미 다른 이벤트나 렌더가 끼어들 수 있었나?”까지 같이 봐야 합니다.

프론트엔드 리뷰에서 자주 보는 위험

코드 냄새왜 위험한가리뷰 질문
setTimeout(fn, 0)으로 순서 보정다음 task로 미룰 뿐, 안정적인 상태 동기화가 아니다왜 다음 턴이어야 하는가?
Promise chain 안에서 DOM/state 대량 갱신microtask가 길면 렌더 기회가 늦어진다한 번에 너무 많은 일을 밀어 넣지 않았는가?
await 뒤에 오래된 값 사용그 사이 다른 작업이 끝났을 수 있다취소/최신성 검사를 했는가?
이벤트 핸들러 안에서 microtask 재귀렌더나 다음 이벤트가 밀릴 수 있다루프가 큐를 독점하지 않는가?

이벤트 루프는 “외울 순서”가 아니라 리뷰할 때 버그의 시간 축을 그리는 도구입니다. 출력 순서 문제, 로딩 상태 깜빡임, 클릭 직후 DOM 측정, 오래된 async 결과 덮어쓰기 모두 같은 질문으로 시작할 수 있습니다.

이 콜백은 어느 큐에 들어가고, 그 전에 어떤 큐가 먼저 비워질까?

Day 8 복습 퀴즈

Quiz1 / 4
Q.첫 예제의 출력 순서로 맞는 것은 무엇일까요?
js
'console.log("A");\nsetTimeout(() => console.log("B"), 0);\nPromise.resolve().then(() => console.log("C")).then(() => console.log("D"));\nconsole.log("E");'

Post Q&A

오케이징에게 물어보기

자바스크립트 퀴즈북 리마인드 Day 8: 이벤트 루프와 Promise 타이밍 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!

0/500

포스트 목록

/study/javascript-quizbook
파일 8개, 폴더 0개
자바스크립트 퀴즈북 리마인드 Day 1: 숫자는 왜 가끔 믿을 수 없을까자바스크립트 퀴즈북 리마인드 Day 2: 같은 값인지 묻는 네 가지 방법자바스크립트 퀴즈북 리마인드 Day 3: + 연산자와 ToPrimitive 흐름자바스크립트 퀴즈북 리마인드 Day 4: 프로퍼티 descriptor와 freeze의 경계자바스크립트 퀴즈북 리마인드 Day 5: 참조, 복사, Map/Set의 메모리 감각자바스크립트 퀴즈북 리마인드 Day 6: 스코프 체인과 호이스팅자바스크립트 퀴즈북 리마인드 Day 7: 클로저 버그와 오래된 값자바스크립트 퀴즈북 리마인드 Day 8: 이벤트 루프와 Promise 타이밍

같은 섹션의 대표 이미지

8 posts · latest first
콜 스택이 비워진 뒤 마이크로태스크 큐가 먼저 실행되고 다음 태스크로 넘어가는 이벤트 루프 다이어그램
Study26. 07. 04.

자바스크립트 퀴즈북 리마인드 Day 8: 이벤트 루프와.

콜 스택, 태스크 큐, 마이크로태스크 큐를 기준으로 Promise와 setTimeout 실행 순서를 코드 리뷰 관점에서 정리합니다.

26. 07. 04.SEOJing
클로저가 생성 위치의 바인딩을 기억해 나중 실행에서 오래된 값을 읽을 수 있음을 보여주는 다이어그램
Study26. 06. 29.

자바스크립트 퀴즈북 리마인드 Day 7: 클로저 버그와 오래된.

클로저가 값 복사가 아니라 렉시컬 환경 참조라는 점을 stale closure, 루프 콜백, React 이벤트 리뷰 관점에서 정리합니다.

26. 06. 29.SEOJing
스코프 체인과 호이스팅 관계를 단순화한 다이어그램
Study26. 06. 28.

자바스크립트 퀴즈북 리마인드 Day 6: 스코프 체인과 호이스팅.

스코프 체인, 클로저, var/let/const 호이스팅 차이를 콜백·상태 버그 리뷰 관점에서 짧게 정리합니다.

26. 06. 28.SEOJing
JavaScript 객체 참조와 Map, Set, WeakMap의 참조 구조를 비교한 다이어그램
Study26. 06. 27.

자바스크립트 퀴즈북 리마인드 Day 5: 참조, 복사,.

객체 참조와 얕은 복사, Object와 Map/Set의 차이, WeakMap/WeakSet이 필요한 메모리 상황을 프론트엔드 코드 리뷰 관점에서 정리합니다.

26. 06. 27.SEOJing
JavaScript 프로퍼티 descriptor가 data descriptor와 accessor descriptor로 갈라지는 구조 다이어그램
Study26. 06. 26.

자바스크립트 퀴즈북 리마인드 Day 4: 프로퍼티.

객체 프로퍼티를 key/value가 아니라 descriptor로 읽는 법, getter/setter와 defineProperty, preventExtensions/seal/freeze의 경계를 코드 리뷰 관점에서 정리합니다.

26. 06. 26.SEOJing
객체가 ToPrimitive를 거쳐 + 연산자의 문자열 연결 또는 숫자 덧셈으로 갈라지는 흐름 다이어그램
Study26. 06. 25.

자바스크립트 퀴즈북 리마인드 Day 3: + 연산자와.

객체가 원시값으로 바뀌는 ToPrimitive 흐름, + 연산자의 문자열 연결과 숫자 덧셈 분기, Symbol.toPrimitive가 코드 리뷰에서 왜 중요한지 정리합니다.

26. 06. 25.SEOJing
==, ===, Object.is, SameValueZero의 차이를 정리한 JavaScript equality 다이어그램
Study26. 06. 24.

자바스크립트 퀴즈북 리마인드 Day 2: 같은 값인지 묻는 네.

==, ===, Object.is, SameValueZero가 각각 어떤 비교 알고리즘을 쓰는지 정리하고, includes와 indexOf, Map/Set 키 비교에서 생기는 프론트엔드 리뷰 포인트를 잡습니다.

26. 06. 24.SEOJing
JavaScript Number, safe integer, NaN, -0, BigInt를 한 장으로 정리한 다이어그램
Study26. 06. 23.

자바스크립트 퀴즈북 리마인드 Day 1: 숫자는 왜 가끔 믿을.

자바스크립트의 Number가 왜 정수처럼 보여도 부동소수점 모델 위에서 움직이는지, NaN과 -0, safe integer, BigInt를 프론트엔드 코드 리뷰 관점에서 다시 정리합니다.

26. 06. 23.SEOJing