코드를 보다 보면 가끔 이런 fetch를 마주친다.
await fetch(API_URL, {
signal: request.signal,
});
처음에는 request에 왜 signal이 붙어 있는지 조금 낯설었다.
request.signal은 AbortSignal이다. 쉽게 말하면 요청이 취소됐는지를 전달하는 신호다. signal이 직접 요청을 취소하는 것은 아니고, 취소가 발생했다는 사실을 fetch 같은 작업에 알려준다.
보통은 AbortController와 함께 사용한다.
const controller = new AbortController();
fetch('/api/posts', {
signal: controller.signal,
});
controller.abort();
abort()가 호출되면 controller.signal을 전달받은 fetch가 중단된다.
서버에서 request.signal을 다른 요청에 그대로 넘기는 경우도 있다.
export async function GET(request: Request) {
const response = await fetch(API_URL, {
signal: request.signal,
});
return response;
}
원래 요청이 취소되면 내부에서 실행 중이던 fetch에도 그 사실이 전달된다. 사용자가 페이지를 떠났는데 서버가 필요 없는 외부 요청을 계속 붙잡고 있는 상황을 줄일 수 있다.
취소된 fetch는 에러를 발생시키기 때문에 필요한 경우 AbortError를 따로 처리해주면 된다.
try {
await fetch(API_URL, { signal: request.signal });
} catch (error) {
if (error instanceof DOMException && error.name === 'AbortError') return;
throw error;
}
정리하면 request.signal은 요청을 취소하는 버튼이라기보다, 요청의 취소 상태를 다른 비동기 작업까지 이어주는 연결선에 가깝다.