AbortController를 활용한 비동기 작업을 효과적으로 제어하기(비동기, dom 이벤트)

박지윤·2024년 6월 5일

1) AbortController란 ?

AbortController는 JavaScript에서 제공되는 기능 중 하나로, 비동기 작업을 취소하는 데 사용됩니다. 주로 Fetch API와 함께 사용되어 네트워크 요청을 중단하거나 프로미스를 취소하는 데 활용이 되죠. 이것은 주로 웹 애플리케이션에서 사용자 경험을 향상시키거나 불필요한 네트워크 요청을 방지하는 데 유용하다.

- AbortController는 하나 이상의 웹 요청을 중단할 수 있는 인터페이스이다.
- 대표적으로 fetch API, Dom Event를 특정 시점에 중단시킬 수 있다.

2) AbortController 장점

  • 사용자 경험 개선
    사용자 경험을 크게 개선할 수 있습니다. AbortController를 사용하면 사용자가 페이지를 떠나거나 다른 동작을 수행할 때 현재 진행 중인 네트워크 요청을 즉시 취소할 수 있습니다. 이를 통해 불필요한 데이터 전송을 막고, 더 나은 사용자 경험을 제공할 수 있습니다.
  • 리소스 관리
    리소스 관리 측면에서도 AbortController는 큰 도움이 됩니다. SPA(Single Page Application)에서는 페이지 이동 시 컴포넌트가 언마운트 되거나, 더 이상 페이지가 필요하지 않은 상황일 때, AbortController를 사용하여 불필요한 네트워크 요청을 중단할 수 있습니다. 이런 점은 SPA(Single Page Application)에서 이점으로 작용합니다.
  • 에러 핸들링
    AbortController를 사용하면 에러 핸들링이 수월해집니다. 네트워크 요청이 중단되었을 때 적절한 에러 핸들링을 해주어야 하는데, AbortController의 signal 속성을 통해 작업이 중단되었는지 확인하고, 그에 맞는 에러 메시지를 출력할 수 있습니다.

3) AbortController 단점

  • 호환성 문제
    호환성에 문제가 있을 수도 있습니다. 대부분의 최신 브라우저에서는 AbortController를 지원하지만 모든 브라우저가 AbortController를 지원하는 것은 아니므로 특정 상황에서 호환성 문제가 발생할 수 있는 점을 염두에 두셔야 합니다.
  • 프로미스 중첩
    AbortController를 사용하다 보면 프로미스 중첩 문제가 발생할 수 있습니다. 비동기 작업을 중단하려면 프로미스를 중첩해서 사용해야하기 때문에 코드가 복잡해질 수 있는 상황이 생길 수 있죠.
  • 프로미스 취소의 한계
    AbortController를 사용한 프로미스 취소에는 한계가 있을 수 있습니다. AbortController로 비동기 작업을 중단하는 것은 프로미스가 생성되고 이미 시작된 이후에만 가능합니다. 따라서 프로미스가 즉시 완료되거나, 이미 진행 중인 네트워크 요청을 중단하는 것은 어려울 수 있습니다.

4) AbortController API

(1) new AbortController()

웹 요청을 중단할 수 있는, AbortController 인터페이스를 생성한다.

(2) AbortController.signal

요청을 취소할 수 있는 AbortSignal 객체 인터페이스를 반환한다
웹 요청 API에 AbortSignal객체의 signal값을 인자로 넘기면, 요청을 취소할 수 있는 상태가 된다.
dom event에도, signal을 인자로 넘기면 이벤트를 취소할 수 있는 상태가 된다

(3) AbortController.abort()

abort() 를 사용하면, signal가 할당된 웹 요청을 취소할 수 있다.

(4) abortSignal.aborted

aborted는 abort()가 실행되어 요청이 취소되었는지 여부를 알 수 있다.

(5) abort event

abort이벤트는 abort()가 실행되어 요청이 중단된 경우 발생한다

5) AbortController 활용법

  • 비동기 처리 중간에 멈추기
    비동기의 경우 중간에 호출을 멈추기 어렵다.
    하지만 어떤 비동기 동작을 요청했는데 너무 오랜 시간이 걸려 취소해야한다면, 방법이 없을까?
    이때 바로 AbortController를 사용하는 것이다!
    AbortController를 사용하면, 비동기 처리를 중간에 멈출 수 있다.

See the Pen AbortController by KumJungMin (@kumjungmin) on CodePen.

  • 이벤트 한 번에 제거하기, removeEventListener의 대안

이벤트 리스너의 경우, removeEventListener를 하지 않으면 이벤트 리스너가 요소보다 오래 남아 메모리 누수가 발생한다.
그렇기에 우리는 이벤트 리스너를 removeEventListener를 사용해 제거해줘야 한다.
그런데 여러 개의 이벤트 리스너가 있는 경우, 일일이 다 removeEventListener로 제거해야하나?
만약 AbortController를 몰랐다면 아래와 같이 제거해야 했을 것이다.

// 이벤트 리스너 등록
btn1.addEventListener('click', onClick);
btn2.addEventListener('click', onClick);
btn3.addEventListener('click', onClick);

// 이벤트 리스너 제거
window.addEventListener('beforeunload', () => {
    btn1.removeEventListener('click', onClick);
    btn2.removeEventListener('click', onClick);
    btn3.removeEventListener('click', onClick);
    };
)

하지만 AbortController를 사용하면, abort()를 호출하여 한 번에 이벤트 리스너를 제거할 수 있다

// AbortController 객체 가져오기
const controller = new AbortController();
const { signal } = controller;

// signal인자를 넘기기
btn1.addEventListener('click', onClick, { signal });
btn2.addEventListener('click', onClick, { signal });
btn3.addEventListener('click', onClick, { signal });

// abort() 호출해서 이벤트 리스너 제거하기
window.addEventListener('beforeunload', () => {
    controller.abort();
    };
)

AbortController를 사용해 웹 요청을 취소하는 방법에 대해 알아보았다
우선 취소하고 싶은 웹 요청 함수에 singal변수를 인자로 넘겨야 했으며, abort()를 실행하면 요청을 취소할 수 있었다
만약 비동기 함수를 중간에 취소해야 하거나 Dom 이벤트를 한 번에 제거하고 싶다면 이 방법을 써도 좋을 듯 하다

참고
https://medium.com/@ehdrbdndns/js-abortcontroller%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%B4-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%98%B8%EC%B6%9C-%EC%A4%91%EC%A7%80%ED%95%98%EA%B8%B0-with-fetch-ea0e8b3fe723

https://developer.mozilla.org/en-US/docs/Web/API/AbortController/AbortController

https://mong-blog.tistory.com/entry/JS-AbortController%EB%A1%9C-%EC%9B%B9-%EC%9A%94%EC%B2%AD-%EC%B7%A8%EC%86%8C%ED%95%98%EA%B8%B0%EB%B9%84%EB%8F%99%EA%B8%B0-dom-%EC%9D%B4%EB%B2%A4%ED%8A%B8

0개의 댓글