Promise와 async/await 제대로 이해하기

어제 "일단 써본" 코드가, 오늘은 왜 그렇게 동작하는지 이해하는 코드가 됩니다

10초 핵심 요약

01

Promise = 진동벨

카페에서 주문하면 진동벨을 받습니다. 그 진동벨 자체가 커피는 아니지만, "커피가 준비되면 알려줄게"라는 약속입니다. Promise도 똑같습니다. fetch()를 호출하는 순간 데이터가 바로 오는 게 아니라, "나중에 응답이 오면 알려줄게"라는 약속(Promise)을 즉시 돌려받습니다.

대기중 (pending)

아직 응답을 기다리는 중. 진동벨이 아직 안 울림

성공 (fulfilled)

요청이 성공적으로 끝남. 진동벨이 울리고 커피를 받음

실패 (rejected)

요청이 실패함. "재료 소진" 안내를 받는 것과 같음

02

타이머로 눈에 보이게 확인하기

fetch는 응답이 몇 초 뒤에 올지 눈으로 예측하기 어려워서 처음 배울 땐 오히려 헷갈립니다. 그래서 네트워크 없이, setTimeout()으로 시간만 흐르는 아주 단순한 Promise를 먼저 만들어 순서를 눈으로 확인해봅니다. 아래 코드를 브라우저 콘솔(F12)에 그대로 붙여넣어 보세요.

console.log('시작');

const waitCoffee = new Promise((resolve) => {
  setTimeout(() => {
    resolve('커피 완성!'); // 2초 뒤에 진동벨이 울린다고 가정
  }, 2000);
});

waitCoffee.then((result) => {
  console.log(result);
});

console.log('그동안 신문 읽기');

실행하면 콘솔에 "시작" → "그동안 신문 읽기" → (2초 뒤) "커피 완성!" 순서로 찍힙니다. .then() 뒤에 있는 console.log('그동안 신문 읽기')가 2초를 기다리지 않고 먼저 실행된다는 점이 핵심입니다 — Promise는 "나중에 값이 온다"는 약속만 걸어두고, 그 사이 나머지 코드는 멈추지 않고 계속 진행됩니다.

03

await은 왜 "기다린다"는 뜻일까

await이 붙은 줄은, 그 Promise가 성공이든 실패든 결론이 날 때까지 바로 다음 줄로 넘어가지 않고 멈춰서 기다립니다. 그 사이 브라우저가 완전히 멈추는 건 아니고(다른 탭 클릭 등은 가능), 그 함수 안에서만 순서대로 진행됩니다.

async function loadPosts() {
  console.log('1. 요청 시작');
  const res = await fetch('/functions/api/posts'); // 여기서 멈춰서 기다림
  console.log('2. 응답 도착'); // 응답이 와야 여기 실행
  const data = await res.json();
  console.log('3. 변환 완료', data);
}

이 세 줄의 console.log는 반드시 1 → 2 → 3 순서로만 찍힙니다. await이 없다면 fetch가 끝나기도 전에 2번과 3번이 먼저 실행되려다 오류가 났을 것입니다.

Promise·async/await은 현직 개발자도 처음엔 헷갈리는 개념입니다. 오늘 한 번에 완전히 이해되지 않아도 괜찮습니다 — Day 33~35에서 fetch/API를 계속 다루며 같은 패턴을 반복해서 보게 되고, 그 과정에서 자연스럽게 익숙해집니다.
04

실패에 대비하기 — try/catch 맛보기

Promise가 실패(rejected)하는데 아무 대비가 없으면 화면에 빨간 오류만 남고 앱이 먹통이 됩니다. try/catch로 감싸면 실패했을 때 할 일을 직접 정할 수 있습니다. 에러 처리는 Day 35에서 본격적으로 다루고, 오늘은 형태만 익힙니다.

async function loadPosts() {
  try {
    const res = await fetch('/functions/api/posts');
    const data = await res.json();
    renderPosts(data);
  } catch (err) {
    console.error('불러오기 실패:', err);
  }
}
05

오늘의 실습 + AI 프롬프트

1위 waitCoffee 예제의 setTimeout 시간을 2000에서 5000으로 바꿔보고, 순서는 그대로인지 콘솔에서 확인합니다.
2Day 31의 loadPosts 함수 각 줄 사이에 console.log를 넣어, 실행 순서를 직접 눈으로 확인합니다.
3일부러 존재하지 않는 URL로 바꿔서 try/catch의 catch 블록이 실행되는지 확인합니다.
AI에게 이렇게 지시해 보세요: "이 fetch 코드를 try/catch로 감싸서, 실패했을 때 화면에 '데이터를 불러오지 못했습니다' 메시지를 보여주도록 수정해줘."
06

Day 32 완료 체크리스트

Promise의 3가지 상태(대기중/성공/실패)를 설명할 수 있다.
waitCoffee 예제로, Promise를 건 뒤에도 나머지 코드가 먼저 실행된다는 걸 직접 확인했다.
await이 다음 줄 실행을 멈추고 기다리게 한다는 걸 console.log로 직접 확인했다.
try/catch로 fetch 실패 상황을 감싸봤다.
스스로 설명해보기 — await이 있는 줄과 없는 줄에서 console.log가 찍히는 순서가 왜 달라지는지 설명할 수 있나요?

오늘의 용어

Promise
나중에 도착할 값의 약속. 대기중/성공/실패 상태를 가짐
setTimeout()
지정한 시간(밀리초)이 지난 뒤에 함수를 실행하는 브라우저 내장 함수
await
Promise가 결론 날 때까지 다음 줄 실행을 멈추고 기다리는 문법
try/catch
에러가 날 수 있는 코드를 감싸, 실패 시 처리를 직접 정하는 문법