[javascript] AbortController를 활용한 fetch 요청 중단

Chan의 기술 블로그·2025년 11월 10일

javascript

목록 보기
7/8

이 글은 『자바스크립트 딥 다이브』에서 다루지 않은 내용으로,
fetch 함수를 활용해 개인 프로젝트를 진행하며 새롭게 배운 점을 정리한 게시물입니다.

fetch 함수는 한 번 실행되면 요청이 완료되기 전까지 중단할 수 없다.
즉, 네트워크 요청이 오래 걸리거나 사용자가 페이지를 벗어나는 상황에서도
기본적으로 요청은 백그라운드에서 계속 진행된다.

이런 문제를 해결하기 위해 AbortController 객체를 사용할 수 있다.
AbortController는 fetch 요청을 중간에 취소(abort) 할 수 있는 기능을 제공한다.


기본 개념

AbortController는 두 가지 핵심 구성요소를 갖는다

구성요소설명
controller요청을 중단할 수 있는 제어 객체
signalfetch 요청에 연결해, 중단 시그널을 전달하는 객체

사용 예시

// 1️⃣ AbortController 생성
const controller = new AbortController();
const { signal } = controller;

// 2️⃣ fetch에 signal 연결
fetch("https://jsonplaceholder.typicode.com/todos/1", { signal })
  .then(res => {
    if (!res.ok) throw new Error(res.statusText);
    return res.json();
  })
  .then(data => console.log("✅ 데이터:", data))
  .catch(err => {
    // 3️⃣ 요청이 중단되었을 때
    if (err.name === "AbortError") {
      console.log("🚫 요청이 중단되었습니다.");
    } else {
      console.error("❌ 오류 발생:", err);
    }
  });

// 4️⃣ 1초 뒤 요청 중단
setTimeout(() => controller.abort(), 1000);

동작 원리

  1. controller가 생성되면, 내부적으로 하나의 시그널(signal)이 함께 만들어진다.
  2. fetch 요청에 { signal } 옵션을 전달하면, 해당 요청은 시그널을 감시한다.
  3. controller.abort()가 호출되면, 연결된 모든 fetch 요청이 즉시 중단되며,
    fetch는 AbortError를 발생시키며 Promise를 reject한다.
  4. catch 블록에서 err.name === "AbortError"로 식별 가능하다.

실무 활용 예시

AbortController는 다음과 같은 상황에서 유용하다:

  • 사용자가 빠르게 페이지 이동 또는 입력 변경 시
    → 이전 요청을 취소해 불필요한 네트워크 낭비 방지
  • 자동완성 검색 API 요청
    → 이전 요청이 완료되기 전 새 요청이 발생하면 이전 것을 즉시 중단
  • SPA(React, Vue 등) 환경에서 컴포넌트 언마운트 시 요청 중단

주의할 점

  • 한 controller는 한 번만 abort 가능하다.
    (중단된 후 다시 재사용할 수 없음 → 새 컨트롤러를 생성해야 함)
  • axios에서도 비슷한 기능이 있지만, axios는 자체 CancelToken 또는 AbortController를 지원한다.

정리

항목fetchAbortController
기본 동작요청 중단 불가요청을 중간에 중단 가능
중단 방법❌ 없음controller.abort() 호출
실무 활용자동완성, 빠른 페이지 이동 시 API 요청 취소매우 유용

예시

자동완성 검색 요청 취소 패턴

let controller;

async function fetchSearch(keyword) {
  // 이전 요청이 있으면 중단
  if (controller) controller.abort();
  controller = new AbortController();

  try {
    const res = await fetch(`/api/search?q=${keyword}`, {
      signal: controller.signal,
    });
    if (!res.ok) throw new Error(res.statusText);
    const data = await res.json();
    console.log("검색 결과:", data);
  } catch (err) {
    if (err.name === "AbortError") {
      console.log("이전 요청 중단됨:", keyword);
    } else {
      console.error("요청 실패:", err);
    }
  }
}

정리 요약

  • fetch는 요청 중단 기능이 기본적으로 없다.
  • AbortController를 사용하면 요청을 중간에 취소할 수 있다.
  • controller.abort() 호출 시 fetch는 AbortError를 던진다.
  • 자동완성, 빠른 입력, 페이지 전환 등에서 불필요한 요청 낭비를 방지할 수 있다.
profile
퍼블리셔에서 프론트앤드로 전향하기

0개의 댓글