Request signal property in Fetch API

Viewed 905

As it can be seen in the reference, Request instance has signal property:

request . signal

Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort event handler.

This snippet shows that req.signal.aborted is false even after a request has been aborted:

let req = new Request('/');
req.signal.onabort = () => console.log('abort'); // no output
let ctrl = new AbortController();
fetch(req, { signal: ctrl.signal })
  .catch(() => console.log(req.signal.aborted)); // outputs false
ctrl.abort();

The result is the same with simulated connection problem (net::ERR_INTERNET_DISCONNECTED).

What is the practical reason for default req.signal to be exposed? Can a request behave differently with reassigned req.signal?

How can req.signal request signal become aborted, i.e. trigger onabort callback and set req.signal to true?

I'm interested in how native Fetch API implementations work internally, there's no specific code problem that needs to be solved.

1 Answers

This snippet shows that req.signal.aborted is false even after a request has been aborted.

Yes. That's because not req is the aborted request, but the request constructed internally by fetch().

Instead, write

let ctrl = new AbortController();
let req = new Request('/', { signal: ctrl.signal });
req.signal.onabort = () => console.log('abort'); // will log
fetch(req).catch(() => console.log(req.signal.aborted)); // outputs true
ctrl.abort();

The req.signal that was created with the new Request constructor here does follow the abort signal of your controller.

Related