본문 바로가기
차근차근

JavaScript 이벤트 루프 완전 정복|콜 스택, 태스크 큐, 마이크로태스크 한눈에 이해하기

by 아빠고미 2025. 5. 21.
반응형

🧠 JavaScript 이벤트 루프 완전 정복|콜 스택, 태스크 큐, 마이크로태스크의 작동 원리

안녕하세요, 퍼블리셔 노미입니다! 😊

오늘은 자바스크립트 개발자라면 반드시 알고 있어야 할 이벤트 루프(Event Loop)의 세계로 들어가 볼 거예요. 🔁

“왜 setTimeout()보다 Promise가 먼저 실행되지?”
async/await정확히 언제 실행될까?”

JavaScript 이벤트 루프 완전 정복|콜 스택, 태스크 큐, 마이크로태스크 한눈에 이해하기

 


이런 궁금증이 있다면, 오늘 글이 아주 큰 도움이 될 거예요! 📚 콜 스택, 태스크 큐, 마이크로태스크까지 비동기 타이밍의 핵심을 부드럽고 시각적으로 정리해드릴게요. 🧩


📌 자바스크립트는 싱글 스레드 언어

먼저 꼭 알아야 할 기본 개념! 자바스크립트는 싱글 스레드(Single Thread) 기반 언어예요. 🧵 즉, 한 번에 한 작업만 처리할 수 있다는 뜻이죠.

그런데도 비동기 처리가 되는 이유는?

  • ✅ 비동기 작업은 JS 엔진이 아닌 브라우저(Web API)가 처리
  • ✅ 완료된 작업은 태스크 큐(Task Queue)로 들어가서 이벤트 루프에 의해 실행됨

→ 이 구조를 정확히 이해하면 모든 비동기 타이밍을 예측할 수 있어요! 👀


🧱 콜 스택(Call Stack)이란?

콜 스택자바스크립트 코드가 실행되는 가장 기본적인 공간입니다. 한 줄 한 줄 동기적으로 실행되며, 함수가 호출될 때마다 위에 쌓이고, 실행이 끝나면 아래로 내려오면서 제거돼요. 📥📤

예시 코드


function greet() {
  console.log('안녕!');
}

function start() {
  greet();
  console.log('시작합니다');
}

start();

실행 순서: start() → greet() → console.log('안녕!') → console.log('시작합니다')

  • 🚶‍♂️ 동기적 처리만 담당
  • 🚫 비동기 함수(setTimeout 등)는 처리 안 함

→ 자바스크립트는 콜 스택에 비동기 작업을 '맡기지 않아요'


🪣 태스크 큐(Task Queue)

비동기 함수(ex. setTimeout(), setInterval())는 브라우저(Web API)가 맡아서 처리하고, 완료된 이후 태스크 큐에 등록돼요. 이때 이벤트 루프가 콜 스택이 비었는지 확인하고, 큐에 있는 작업을 스택으로 밀어 넣습니다. 🔄

예시


console.log('1');

setTimeout(() => {
  console.log('2'); // 태스크 큐로 이동
}, 0);

console.log('3');

출력 순서: 1 → 3 → 2

  • 📥 setTimeout은 Web API에게 위임
  • 📤 완료되면 태스크 큐에 들어감
  • 📦 콜 스택이 비었을 때 실행됨

⚡ 마이크로태스크(Microtask Queue)

Promise.then(), async/await, queueMicrotask()마이크로태스크 큐에 들어갑니다. 이 큐는 태스크 큐보다 우선순위가 높아요! 🥇

예시


console.log('A');

Promise.resolve().then(() => {
  console.log('B');
});

setTimeout(() => {
  console.log('C');
}, 0);

console.log('D');

출력 순서: A → D → B → C
✔️ B는 마이크로태스크 큐 ✔️ C는 태스크 큐

→ 마이크로태스크는 콜 스택이 비자마자 가장 먼저 실행돼요!


📊 실행 순서 실전 예제 정리

예제 1


console.log('1');

setTimeout(() => {
  console.log('2');
}, 0);

Promise.resolve().then(() => {
  console.log('3');
});

console.log('4');

실행 순서:

  1. 1️⃣ '1' → 동기
  2. 4️⃣ '4' → 동기
  3. 3️⃣ '3' → 마이크로태스크
  4. 2️⃣ '2' → 태스크 큐 (setTimeout)

최종 출력: 1 → 4 → 3 → 2


예제 2: async/await 포함


async function test() {
  console.log('A');
  await null;
  console.log('B');
}

test();
console.log('C');

실행 순서:

  • 🧱 A → 동기
  • 🧠 await 이후 → 마이크로태스크
  • 🧱 C → 동기
  • ⚡ B → 마이크로태스크

결과: A → C → B


🎞️ 이벤트 루프 흐름 애니메이션 (텍스트 버전)


[1단계] 코드 실행 시작
  ↳ 동기 함수 → 콜 스택에 쌓임 → 실행됨

[2단계] 비동기 함수 호출
  ↳ setTimeout → 브라우저에 맡김
  ↳ Promise → 마이크로태스크 큐에 등록

[3단계] 콜 스택이 비면
  ↳ 마이크로태스크 큐 먼저 처리
  ↳ 그다음 태스크 큐 처리

→ 모든 흐름은 "콜 스택이 비었을 때" 순서대로 실행돼요! 🔄


🧠 마무리 요약

✔️ 핵심 키워드 정리

  • 🧱 콜 스택 → 동기 실행의 중심
  • 🪣 태스크 큐 → setTimeout 등 비동기 후 처리
  • ⚡ 마이크로태스크 큐 → Promise, async/await → 우선순위 높음
  • 🔁 이벤트 루프 → 스택이 비면 큐로부터 작업을 가져옴

🔥 꼭 기억하세요!

자바스크립트는 싱글 스레드지만 이벤트 루프 구조 덕분에 동시 처리가 가능합니다! 🧠 Promise나 setTimeout의 동작 순서가 궁금할 땐 “콜 스택 → 마이크로태스크 → 태스크 큐” 흐름을 꼭 떠올리세요!


다음 글에서는 📦 **requestAnimationFrame, 이벤트 위임 등 브라우저 내부 실행 메커니즘**도 이어서 소개할게요! 끝까지 읽어주셔서 감사합니다! 🙌✨


#JavaScript이벤트루프 #콜스택 #태스크큐 #마이크로태스크 #비동기실행순서 #퍼블리셔노미 #JS심화 #프론트엔드이론 #이벤트루프정리

반응형