티스토리 뷰

반응형

TL;DR(Too Long; Didn't Read). 요약.

AbortController API를 사용해 응답이 반환되지 않은 비동기 요청을 취소할 수 있다.

const abortController = new AbortController();
fetch(request, {signal: abortController.signal}) // signal을 설정한다.
  .then(doSomthing)
});
abortController.abort(); // 원할 때 호출하면, signal을 등록한 요청을 취소한다.

 

 

 

 

전형적인 웹에서는 한번 요청이 시작하면 취소하는 것이 불가했고 그럴 필요성도 별로 없었다. 요청을 취소해야할 만한 상황이 발생한다면 요청 자체를 정말 필요한 때에만 수행하도록 처리하는 방식으로 다뤄왔을 것이다. 그렇지 않을 경우 원치 않는 응답에 대한 결과 처리가 부가적으로 필요했을 것이다.

 

하지만 이제는 AbortController API를 활용하여 응답이 반환되지 않은 요청을 취소할 수 있다.

 

과도한 새로운 정보 요청은 클라이언트(렌더링)와 서버(응답)에 부하를 주며 상용 서비스에서는 보통 비용으로도 이어진다. 따라서 필요한 시점에 요청할 수 있도록 처리가 필요하다.

중요한 점.

AbortController API는 클라이언트 API이므로, 요청을 취소한다고해도 이미 전송된 요청은 서버가 그대로 받는다. 브라우저가 자신이 전송한 요청의 응답에 대한 핸들링을 취소한다 정도로 이해하면 좋을 것 같다.

(이제와 생각해보니, 이미 서버로 날아간 요청을 어떻게 취소할 수 있다고 생각했었는지...)

 

지도를 포함하는 페이지가 있고, 지도를 이동할 때마다 화면에 나타나는 영역에 해당하는 새로운 정보를 서버로 요청하는 기능을 구현하였다고 가정해보자.

지도의 이동(move)이 발생할 때마다 새로운 정보를 요청한다면 셀 수 없이 많은 수의 요청이 발생할 것이고, 그에 따라 필요한 처리도 늘어날 것이다. 그래서 보통은 지도의 이동이 끝났을 때(moveend) 새로운 정보를 요청하는 방식을 사용한다.

하지만 원하는 영역이 나타날 때 까지 빠르게 연속해서 지도를 이동한다면, 응답이 오기전에 새로운 요청을 계속해서 생성하게 되고 응답이 오지 않은 과거의 요청은 그 의미를 잃게 된다.

 

이 경우, 각 요청에 대해 다음과 같이 AbortController를 생성하고 그 signal을 요청하는 fetch에게 넘겨주자.

map.on("moveend", (e) => {
  const abortController = new AbortController();
  fetch(request, {signal: abortController.signal})
      .then(doSomthing)
});

그 다음, 취소가 필요할 때 abortController의 abort 메소드를 호출하면된다.

let isPending = false;
let abortController;

map.on("moveend", (e) => {
  if (isPending) { // 요청이 pending 상태일 때 취소
	abortController.abort();
  }

  abortController = new AbortController();
  isPending = true;

  fetch(request, {signal: abortController.signal})
      .then((res) => {
        doSomething
      })
      .finally(() => {
      	isPending = false;
      });
});

 

자세한 내용은 MDN을 참조하자.

https://developer.mozilla.org/ko/docs/Web/API/AbortController/abort

 

AbortController.abort()

AbortController 인터페이스의 abort() 메소드는 DOM 요청(Fetch 요청과 같은)이 완료되기 전에 취소한다. 이를 통해 fetch 요청, 모든 응답 Body 소비, 스트림을 취소할 수 있다.

developer.mozilla.org

반응형
댓글