Antworten:
fetch
unterstützt jetzt einen signal
Parameter ab dem 20. September 2017, aber derzeit scheinen dies nicht alle Browser zu unterstützen .
2020 UPDATE: Die meisten gängigen Browser (Edge, Firefox, Chrome, Safari, Opera und einige andere) unterstützen die Funktion , die Teil des DOM-Lebensstandards geworden ist . (Stand 5. März 2020)
Dies ist eine Änderung, die wir jedoch sehr bald sehen werden. Daher sollten Sie in der Lage sein, eine Anfrage mit einem AbortController
s abzubrechen AbortSignal
.
So funktioniert es:
Schritt 1 : Sie erstellen ein AbortController
(Vorerst ich nur verwendet diese )
const controller = new AbortController()
Schritt 2 : Sie erhalten das AbortController
s-Signal wie folgt:
const signal = controller.signal
Schritt 3 : Sie übergeben das signal
zu holen wie folgt:
fetch(urlToFetch, {
method: 'get',
signal: signal, // <------ This is our AbortSignal
})
Schritt 4 : Brechen Sie einfach ab, wann immer Sie müssen:
controller.abort();
Hier ist ein Beispiel, wie es funktionieren würde (funktioniert unter Firefox 57+):
<script>
// Create an instance.
const controller = new AbortController()
const signal = controller.signal
/*
// Register a listenr.
signal.addEventListener("abort", () => {
console.log("aborted!")
})
*/
function beginFetching() {
console.log('Now fetching');
var urlToFetch = "https://httpbin.org/delay/3";
fetch(urlToFetch, {
method: 'get',
signal: signal,
})
.then(function(response) {
console.log(`Fetch complete. (Not aborted)`);
}).catch(function(err) {
console.error(` Err: ${err}`);
});
}
function abortFetching() {
console.log('Now aborting');
// Abort.
controller.abort()
}
</script>
<h1>Example of fetch abort</h1>
<hr>
<button onclick="beginFetching();">
Begin
</button>
<button onclick="abortFetching();">
Abort
</button>
AbortController is not defined
. Auf jeden Fall ist dies nur ein Proof of Concept, zumindest Leute mit Firefox 57+ können sehen, dass es funktioniert
https://developers.google.com/web/updates/2017/09/abortable-fetch
https://dom.spec.whatwg.org/#aborting-ongoing-activities
// setup AbortController
const controller = new AbortController();
// signal to pass to fetch
const signal = controller.signal;
// fetch as usual
fetch(url, { signal }).then(response => {
...
}).catch(e => {
// catch the abort if you like
if (e.name === 'AbortError') {
...
}
});
// when you want to abort
controller.abort();
funktioniert in Edge 16 (2017-10-17), Firefox 57 (2017-11-14), Desktop Safari 11.1 (2018-03-29), iOS Safari 11.4 (2018-03-29), Chrome 67 (2018-05) -29) und später.
In älteren Browsern können Sie die whatwg-fetch-Polyfüllung von github und die AbortController- Polyfüllung verwenden . Sie können ältere Browser erkennen und die Polyfills auch bedingt verwenden :
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
import {fetch} from 'whatwg-fetch'
// use native browser implementation if it supports aborting
const abortableFetch = ('signal' in new Request('')) ? window.fetch : fetch
Stand Februar 2018, fetch()
kann mit dem folgenden Code in Chrome gekündigt werden (siehe Verwenden lesbarer Streams , um die Firefox-Unterstützung zu aktivieren). Es wird kein Fehler catch()
zum Aufnehmen ausgegeben, und dies ist eine vorübergehende Lösung, bis sie AbortController
vollständig übernommen ist.
fetch('YOUR_CUSTOM_URL')
.then(response => {
if (!response.body) {
console.warn("ReadableStream is not yet supported in this browser. See https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream")
return response;
}
// get reference to ReadableStream so we can cancel/abort this fetch request.
const responseReader = response.body.getReader();
startAbortSimulation(responseReader);
// Return a new Response object that implements a custom reader.
return new Response(new ReadableStream(new ReadableStreamConfig(responseReader)));
})
.then(response => response.blob())
.then(data => console.log('Download ended. Bytes downloaded:', data.size))
.catch(error => console.error('Error during fetch()', error))
// Here's an example of how to abort request once fetch() starts
function startAbortSimulation(responseReader) {
// abort fetch() after 50ms
setTimeout(function() {
console.log('aborting fetch()...');
responseReader.cancel()
.then(function() {
console.log('fetch() aborted');
})
},50)
}
// ReadableStream constructor requires custom implementation of start() method
function ReadableStreamConfig(reader) {
return {
start(controller) {
read();
function read() {
reader.read().then(({done,value}) => {
if (done) {
controller.close();
return;
}
controller.enqueue(value);
read();
})
}
}
}
}
Derzeit gibt es keine richtige Lösung, wie @spro sagt.
Wenn Sie jedoch eine Antwort während des Flugs haben und ReadableStream verwenden, können Sie den Stream schließen, um die Anforderung abzubrechen.
fetch('http://example.com').then((res) => {
const reader = res.body.getReader();
/*
* Your code for reading streams goes here
*/
// To abort/cancel HTTP request...
reader.cancel();
});
Lassen Sie uns polyfill:
if(!AbortController){
class AbortController {
constructor() {
this.aborted = false;
this.signal = this.signal.bind(this);
}
signal(abortFn, scope) {
if (this.aborted) {
abortFn.apply(scope, { name: 'AbortError' });
this.aborted = false;
} else {
this.abortFn = abortFn.bind(scope);
}
}
abort() {
if (this.abortFn) {
this.abortFn({ reason: 'canceled' });
this.aborted = false;
} else {
this.aborted = true;
}
}
}
const originalFetch = window.fetch;
const customFetch = (url, options) => {
const { signal } = options || {};
return new Promise((resolve, reject) => {
if (signal) {
signal(reject, this);
}
originalFetch(url, options)
.then(resolve)
.catch(reject);
});
};
window.fetch = customFetch;
}
Bitte beachten Sie, dass der Code nicht getestet wird! Lassen Sie mich wissen, wenn Sie es getestet haben und etwas nicht funktioniert hat. Möglicherweise erhalten Sie Warnungen, dass Sie versuchen, die Funktion "Abrufen" aus der offiziellen JavaScript-Bibliothek zu überschreiben.