How to Cancel a Fetch Request

2019 Year in Review

JavaScript promises have always been a major win for the language — they’ve led to a revolution of asynchronous coding that has vastly improved performance on the web. One shortcoming of native promises is that there’s no true way to cancel a fetch…until now. A new AbortController has been added to the JavaScript specification that will allow developers to use a signal to abort one or multiple fetch calls.

Here’s the flow of how canceling a fetch call works:

  • Create an AbortController instance
  • That instance has a signal property
  • Pass the signal as a fetch option for signal
  • Call the AbortController‘s abort property to cancel all fetches that use that signal.

Aborting a Fetch

The following is the bare bones of canceling a fetch request:

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

fetch("http://localhost:8000",  signal ).then(response => 
    console.log(`Request 1 is complete!`);
).catch(e => 
    console.warn(`Fetch 1 error: $e.message`);
);

// Abort request
controller.abort();

An AbortError occurs upon the abort call, so you can listen for aborted fetches in the catch by comparing the error name:

}).catch(e => 
    if(e.name === "AbortError") 
        // We know it's been canceled!
    
);

Passing the same signal to multiple fetch calls will cancel all requests with that signal:

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

fetch("http://localhost:8000",  signal ).then(response => 
    console.log(`Request 1 is complete!`);
).catch(e => 
    console.warn(`Fetch 1 error: $e.message`);
);

fetch("http://localhost:8000",  signal ).then(response => 
    console.log(`Request 2 is complete!`);
).catch(e => 
    console.warn(`Fetch 2 error: $e.message`);
);

// Wait 2 seconds to abort both requests
setTimeout(() => controller.abort(), 2000);

In his article Abortable fetch, Jake Archibald details a nice utility for creating abortable fetches without the need for all of the boilerplate:

function abortableFetch(request, opts) 
  const controller = new AbortController();
  const signal = controller.signal;

  return 
    abort: () => controller.abort(),
    ready: fetch(request,  ...opts, signal )
  ;

If I’m completely honest, I’m not super excited about the method for canceling fetches. In an ideal world, a basic .cancel() on the Promise returned by a fetch would be cool, but there are issues that would come with that too. In any event, I’m jazzed about being able to cancel fetch calls and you should be too!

The post How to Cancel a Fetch Request appeared first on David Walsh Blog.

Leave a Reply

Your email address will not be published. Required fields are marked *