JavaScript에서 fetch로 API 데이터를 가져온 뒤 바로 data.map(...)을 호출했는데 화면이 비는 경우가 많습니다. 코드는 짧아 보이지만 실제 원인은 대부분 Promise를 배열처럼 사용했거나, 응답을 JSON으로 바꾸기 전에 렌더링하려고 했기 때문입니다.

자주 나오는 실패 코드

const users = fetch("/api/users");

users.map(user => {
  return `<li>${user.name}</li>`;
});

이 코드는 users가 배열이라고 가정합니다. 하지만 fetch()가 돌려주는 값은 배열이 아니라 Promise입니다. Promise는 아직 끝나지 않은 작업을 나타내기 때문에 map을 바로 호출할 수 없습니다.

왜 화면이 비어 보이나요?

  • fetch()는 네트워크 요청을 시작하고 Promise를 반환합니다.
  • 응답 본문은 response.json()으로 한 번 더 파싱해야 합니다.
  • 데이터가 도착하기 전에 렌더링하면 배열이 없어서 빈 화면이나 오류가 납니다.
  • 실무에서는 로딩, 실패, 빈 데이터, 성공 상태를 나눠야 원인을 빨리 찾을 수 있습니다.

수정 코드: await로 순서를 명확히 나누기

async function loadUsers() {
  const response = await fetch("/api/users");

  if (!response.ok) {
    throw new Error("사용자 목록을 불러오지 못했습니다.");
  }

  const users = await response.json();

  return users.map(user => {
    return `<li>${user.name}</li>`;
  }).join("");
}

핵심은 세 단계입니다. 첫째, fetch 요청이 끝날 때까지 기다립니다. 둘째, 응답을 JSON 데이터로 변환합니다. 셋째, 그 데이터가 배열인지 확인한 뒤 화면에 렌더링합니다.

실무 체크리스트

  • fetch() 결과를 변수에 담았을 때 그 값이 Promise인지 확인합니다.
  • await response.json()을 빠뜨리지 않았는지 봅니다.
  • API 실패 시 response.ok를 확인합니다.
  • 데이터가 배열이 아닐 가능성이 있으면 Array.isArray(data)로 방어합니다.
  • 화면에는 로딩, 에러, 빈 결과, 성공 결과를 각각 표시합니다.

직접 풀어볼 문제

아래 실습에서는 fetch 흐름을 함수로 분리하고, Promise와 실제 배열 데이터를 구분하는 연습을 할 수 있습니다.

JavaScript fetch/async 실습 문제 풀기

해설팩으로 이어서 보기

숫자 문자열 계산, 배열 원본 변경, fetch/async 흐름, DOM 이벤트 중복 등록처럼 실무 화면에서 자주 깨지는 JavaScript 실수를 실패 코드와 수정 코드로 정리했습니다.

JavaScript 실무 실수 해설팩 샘플 보기

이메일로 샘플을 받고 싶다면 아래 신청 페이지에서 JavaScript 해설팩을 선택하면 됩니다.

프론트엔드 실무 해설팩 신청하기


프론트엔드 실무 코딩 랩에서 더 알아보기

구독을 신청하면 최신 게시물을 이메일로 받아볼 수 있습니다.

댓글 남기기

← 뒤로

응답해 주셔서 감사합니다. ✨

프론트엔드 실무 코딩 랩에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기

프론트엔드 실무 코딩 랩에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기