Jawaban:
fetch
sekarang mendukung signal
parameter pada 20 September 2017, tetapi tidak semua browser mendukung hal ini saat ini .
UPDATE 2020: Sebagian besar browser utama (Edge, Firefox, Chrome, Safari, Opera, dan beberapa lainnya) mendukung fitur ini , yang telah menjadi bagian dari standar hidup DOM . (per 5 Maret 2020)
Ini adalah perubahan yang akan segera kami temui, jadi Anda harus dapat membatalkan permintaan dengan menggunakan AbortController
s AbortSignal
.
Cara kerjanya adalah ini:
Langkah 1 : Anda membuat AbortController
(Untuk saat ini saya baru saja menggunakan ini )
const controller = new AbortController()
Langkah 2 : Anda mendapatkan AbortController
sinyal seperti ini:
const signal = controller.signal
Langkah 3 : Anda lulus signal
untuk mengambil seperti:
fetch(urlToFetch, {
method: 'get',
signal: signal, // <------ This is our AbortSignal
})
Langkah 4 : Batalkan saja kapan pun Anda perlu:
controller.abort();
Berikut ini contoh cara kerjanya (berfungsi di 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
. Pokoknya ini hanya bukti konsep, setidaknya orang-orang dengan Firefox 57+ dapat melihatnya berfungsi
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();
bekerja di 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) -29), dan nanti.
pada browser lama, Anda dapat menggunakan polyfill whatwg-fetch github dan AbortController polyfill . Anda dapat mendeteksi browser yang lebih lama dan menggunakan polyfill secara kondisional juga:
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
Mulai Februari 2018, fetch()
dapat dibatalkan dengan kode di bawah ini di Chrome (baca Menggunakan Aliran yang Dapat Dibaca untuk mengaktifkan dukungan Firefox). Tidak ada kesalahan yang dilemparkan untuk catch()
mengambil, dan ini adalah solusi sementara sampai AbortController
sepenuhnya diadopsi.
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();
})
}
}
}
}
Adapun saat ini tidak ada solusi yang tepat, seperti kata @spro.
Namun, jika Anda memiliki respons dalam penerbangan dan menggunakan ReadableStream, Anda dapat menutup streaming untuk membatalkan permintaan.
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();
});
Mari 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;
}
Perlu diingat bahwa kode ini tidak diuji! Beri tahu saya jika Anda telah mengujinya dan ada yang tidak berhasil. Mungkin memberi Anda peringatan bahwa Anda mencoba untuk menimpa fungsi 'fetch' dari perpustakaan resmi JavaScript.