본문 바로가기
웹 프론트엔드/Javascript

AbortController를 사용해 API 비동기요청 취소하기

by canoe726 2020. 10. 3.
728x90

최근 Javascript 웹 페이지 제작을 하면서 fetch를 통한 비동기요청이 진행되는 동안에 요청을 취소해야하는 기능구현이 필요하게 되었다.

 

페이지 이동, 취소 요청과 같은 이벤트가 발생하게 되면 이전 비동기요청을 취소하는 방법에 대해서 알아보다 이를 더 잘 이해하기 위해 포스팅을 작성하게 되었습니다.

 

 

1. AbortController 개요

 

Fetch 객체는 promise 객체를 리턴하는 비동기함수입니다.

 

 

원래 promise 객체는 자체 abort 기능이 없기 때문에 abortcontroller 를 통해서 비동기 동작 중단 기능을 구현 할 수 있습니다.

 

 

- 사용해야 하는 이유

 

1) 필요하지 않은 API 호출을 취소하여 웹페이지 성능개선

 

2) API 호출로 인해 발생하는 비용 절감

 

 

2. 기본적인 사용방법

 

AbortController 객체를 사용하는 순서는 3단계로 구분할 수 있습니다.

 

 

2-1. AbortController 선언

 

let controller = new AbortController;

 

2-2. Fetch 함수에 signal 파라미터 할당

 

fetch(url, { signal: controller.signal });

 

2-3. abort 함수 호출

 

controller.abort();

 

 

- 완성된 코드

 

const url = '';
let controller = new AbortController;
fetch(url, { signal: controller.signal });
controller.abort();

 

 

- AbortController 구성 및 동작원리

 

1) 구성 : AbortController는 signal 이라는 속성(property)과 abort 라는 메소드(method)로 구성되어 있다.

 

2) 동작원리 : abort 메소드 호출시 signal 속성이 호출되고 controller.signal.aborted 속성이 true가 된다.

 

3) 예외처리 : abort가 발생하면 try, catch 문에서 'AbortError'로 catch 한다.

 

if (err.name == 'AbortError') {
	// handle abort()
    alert("Aborted!");
}

 

 

3. AbortController를 사용한 예제

 

구현할 예제 - 영화 API 비동기호출 및 취소 이벤트 구현

 

3-1. 환경

 

1) 영화 API 주소

 

 

API Documentation - YTS YIFY

Official YTS YIFY API documentation. YTS offers free API - an easy way to access the YIFY movies details.

yts.mx

 

2) 서버 : 확장 프로그램을 통해서 실행

 

 

Web Server for Chrome

A Web Server for Chrome, serves web pages from a local folder over the network, using HTTP. Runs offline.

chrome.google.com

 

 

3-2. 요구사항

 

1) 영화 API를 통해 평점순, 이름순 버튼을 각 각 클릭하면 평점순 데이터 10개, 이름순 데이터 10개를 가져온다. 

2) 데이터를 모두 가져오는데 성공하면 10개 영화 데이터를 화면에 띄운다.


3) 만약 평점순 버튼을 클릭하여 평점순 데이터를 10개 가져오는 도중에 이름순 버튼을 클릭하면 기존의 평점순 API 요청을 취소시키고 이름순 데이터를 10개 가져온다. (그 반대도 동일하게 구현한다.)

 

 

+ 예외 처리

 

1) API 호출이 실패하면 404-not-found 이미지와 에러 내용을 출력한다.

 

2) 버튼을 클릭하면 데이터를 가져오고 있다는 loading UI 처리를 해준다.

 

3) 10개 데이터를 가져왔지만 서버 에러로 인해 0개를 가져왔다면 API 호출 실패를 알려주는 UI 처리를 해준다.

 

4) ES6 문법을 사용하여 모듈화 한다.

 

 

3-3. Abort 기능 구현 코드

 

const BASE_MOVIE_URL = 'https://yts.mx/api/v2/';
const GET_TITLE = 'list_movies.json?sort=title&page=3&limit=10';

// fetch가 진행중인지 검사하는 boolean 변수
let whileFetching = false;
// AbortController 객체를 담는 변수
let abortController;

const request = async url => {
    try {
        // fetch가 진행중이면 abort() 메소드로 취소시킴
        if(whileFetching) abortController.abort();

        abortController = new AbortController;
        whileFetching = true;

        // abort 기능을 사용하기 위해 fetch 메소드의 signal 파라미터에 AbortController signal 속성 대입
        const response = await fetch(url, {
            signal: abortController.signal
        });

        if(response.ok) {
            const result = await response.json();
            // fetch를 통해 데이터를 가져오는데 성공한 경우 fetch가 끝났기 때문에 변수 whileFetch에 false 대입
            whileFetching = false;
            return result;
        } else {
            const err = await response.json();
            throw err;
        }
    } catch(e) {
        // abort 메소드 호출시 'AbortError'로 예외처리됨
        if(e.name === 'AbortError') {
            throw {
                status: 'FetchAbort'
            }
        }
        throw {
            message: e.message,
            status: e.status
        }
    }
};

const api = {
    getMoviesByTitle: async () => {
        try {
            const response = await request(BASE_MOVIE_URL + GET_TITLE);
            return {
                isError: false,
                data: response
            }
        } catch(e) {
            return {
                isError: true,
                data: e
            }
        }
    }
};

export { api };

 

* 구현시 주의사항

 

1) whileFetch 변수를 통해 fetch가 진행중인지를 확인하고 abort 메소드를 호출한다.

 

2) fetch 메소드를 호출할 때, async, await 키워드를 사용하여 비동기호출 후 진행할 코드 순서를 정해준다.

 

3) fetch 메소드를 호출할 때, api 호출이 실패할 경우가 생길 수 있기 때문에 try catch 키워드를 통해 예외처리를 한다.

 

 

3-4. 구현된 결과

 

 

yts.mx 영화 API 호출

 

 

API 호출이 겹치면 이전 API 호출을 abort 하는 예제

 

 

* 예제 소스코드 레포지터리

 

Readme 에 더 자세한 내용이 기재되어 있습니다.

 

 

GitHub - canoe726/theMovieApi: yts.mx 영화 API 호출 웹 페이지

yts.mx 영화 API 호출 웹 페이지. Contribute to canoe726/theMovieApi development by creating an account on GitHub.

github.com

 

 

 

- 참고한 사이트

 

1. MDN 홈페이지

 

AbortController - Web APIs | MDN

The AbortController interface represents a controller object that allows you to abort one or more Web requests as and when desired.

developer.mozilla.org

 

2. ko.javascript

 

Fetch: Abort

 

ko.javascript.info

 

 

728x90

댓글