axios cancel (비동기 처리)

천영석·2021년 9월 29일
1

간단하게 배운 것을 작성하려고 한다.

크루의 블로그를 보고 abortController에 대해 알게 되었다. 블로그에 보면 자세하게 나와 있는데, fetch의 두 번째 인자에 abortController의 메소드인 signal을 할당하고, 취소하고 싶을 때 해당 signal을 취소하는 abort() 메소드를 사용하면 된다.

const controller = new AbortController();
const signal = controller.signal;

fetch(url, {signal});

controller.abort();

대략 이런 모습이다. signal을 등록하고, 취소하고 싶을 때 abort로 취소하고 흐름은 어렵지 않다. fetch는 해당 api를 지원해서 쉽게 사용할 수 있지만 일반적인 Promise에서 사용하려면 abort 이벤트를 사용해서 직접 등록해야 한다고 한다. 우리 프로젝트에서는 axios를 사용하고 있었기 때문에 어떻게하지 고민하다가 공식 문서에 들어가봤다.

다행히도 axios도 요청을 취소할 수 있는 기능을 지원하고 있었다. 문서

CancelToken을 활용한 것으로 axios의 config에 등록해서 사용할 수 있다. 이미 철회된 proposal-cancelable-promises를 기반으로 동작한다는데... 괜찮겠지?? 이것까지는 잘 모르겠다.

문서에서는 두 가지의 방법을 제시하는데,

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

위처럼 source를 만들어 cancelToken에 할당해두고, 필요할 때 cancel을 하는 방법과

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();

CancelToken에 콜백함수를 할당해 cancel이라는 변수의 값을 바꿔주는 방식으로 abortController와 비슷한 방식으로 cancel을 할 수 있는 방법을 보여주고 있다.

처음 방법을 사용해본 느낌으로는 cancel을 한번 하고 나면 다시 요청했을 때, 요청을 보내지도 않고 그냥 취소된 상태가 남아있는 것 같았다. 그리고 cancelToken에 같은 source.token을 할당해두면 모든 요청이 취소될 것 같다.(아직 안해봄)
한번 취소되고 나면 다시 풀 방법을 모르겠어서 아래의 방법을 사용했다.

아래의 방법은 abortController와 같았다. 요청을 보낼 때마다 signal과 같은 cancleToken을 할당하고, 취소하고 싶으면 호출해서 취소하면 됐다. 요청할 때마다 최상단에서 cancel()을 호출하기만 하면 이전 cancelToken을 조회해서 요청이 아직 진행 중이라면 취소가 된다.

cancel?.(); // <- 추가된 코드
const tagKeywords = await getTagKeywordAsync(searchKeyword);

요약해서 보여주면 위처럼 cancel이 있을 때 실행하도록 한줄만 추가했다.

이렇게 간단한 방법으로 마지막 api만 실행할 수 있게 되었다. 하지만 아직 실험만 해본 상태이고 동작하는 방식을 자세하게 모르기 때문에 더 공부를 해보려고 한다.

profile
느려도 꾸준히 발전하려고 노력하는 사람입니다.

0개의 댓글