Saya punya fetch-api
POST
permintaan:
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
Saya ingin tahu apa waktu tunggu default untuk ini? dan bagaimana kita bisa mengaturnya ke nilai tertentu seperti 3 detik atau detik tak terbatas?
javascript
ajax
fetch-api
Akshay Lokur
sumber
sumber
.reject()
memenuhi janji yang sudah diselesaikan tidak akan menghasilkan apa-apa.Saya sangat suka pendekatan bersih dari inti ini menggunakan Promise.race
fetchWithTimeout.js
export default function (url, options, timeout = 7000) { return Promise.race([ fetch(url, options), new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout) ) ]); }
main.js
import fetch from './fetchWithTimeout' // call as usual or with timeout as 3rd argument fetch('http://google.com', options, 5000) // throw after max 5 seconds timeout error .then((result) => { // handle result }) .catch((e) => { // handle errors and timeout error })
sumber
fetch
kesalahan terjadi setelah waktu tunggu. Ini bisa diselesaikan dengan menangani (.catch
)fetch
kegagalan dan melempar ulang jika waktu tunggu belum terjadi.Dengan menggunakan AbortController , Anda dapat melakukan ini:
const controller = new AbortController(); const signal = controller.signal; const fetchPromise = fetch(url, {signal}); // 5 second timeout: const timeoutId = setTimeout(() => controller.abort(), 5000); fetchPromise.then(response => { // completed request before timeout fired // If you only wanted to timeout the request, not the response, add: // clearTimeout(timeoutId); })
sumber
Berdasarkan jawaban yang sangat baik dari Endless , saya membuat fungsi utilitas yang bermanfaat.
const fetchTimeout = (url, ms, { signal, ...options } = {}) => { const controller = new AbortController(); const promise = fetch(url, { signal: controller.signal, ...options }); if (signal) signal.addEventListener("abort", () => controller.abort()); const timeout = setTimeout(() => controller.abort(), ms); return promise.finally(() => clearTimeout(timeout)); };
const controller = new AbortController(); document.querySelector("button.cancel").addEventListener("click", () => controller.abort()); fetchTimeout("example.json", 5000, { signal: controller.signal }) .then(response => response.json()) .then(console.log) .catch(error => { if (error.name === "AbortError") { // fetch aborted either due to timeout or due to user clicking the cancel button } else { // network error or json parsing error } });
Semoga membantu.
sumber
belum ada dukungan waktu tunggu dalam fetch API. Tapi itu bisa dicapai dengan membungkusnya dengan janji.
untuk mis.
function fetchWrapper(url, options, timeout) { return new Promise((resolve, reject) => { fetch(url, options).then(resolve, reject); if (timeout) { const e = new Error("Connection timed out"); setTimeout(reject, timeout, e); } }); }
sumber
EDIT : Permintaan pengambilan akan tetap berjalan di latar belakang dan kemungkinan besar akan mencatat kesalahan di konsol Anda.
Memang
Promise.race
pendekatannya lebih baik.Lihat tautan ini untuk referensi Promise.race ()
Balapan berarti semua Janji akan berjalan pada waktu yang sama, dan balapan akan berhenti segera setelah salah satu Janji mengembalikan nilai. Oleh karena itu, hanya satu nilai yang akan dikembalikan . Anda juga bisa meneruskan fungsi untuk dipanggil jika waktu pengambilan habis.
fetchWithTimeout(url, { method: 'POST', body: formData, credentials: 'include', }, 5000, () => { /* do stuff here */ });
Jika ini menarik minat Anda, penerapan yang mungkin adalah:
function fetchWithTimeout(url, options, delay, onTimeout) { const timer = new Promise((resolve) => { setTimeout(resolve, delay, { timeout: true, }); }); return Promise.race([ fetch(url, options), timer ]).then(response => { if (response.timeout) { onTimeout(); } return response; }); }
sumber
Anda dapat membuat pembungkus timeoutPromise
function timeoutPromise(timeout, err, promise) { return new Promise(function(resolve,reject) { promise.then(resolve,reject); setTimeout(reject.bind(null,err), timeout); }); }
Anda kemudian dapat membungkus janji apa pun
timeoutPromise(100, new Error('Timed Out!'), fetch(...)) .then(...) .catch(...)
Ini tidak akan benar-benar membatalkan koneksi yang mendasarinya tetapi akan memungkinkan Anda untuk membuat janji habis waktu.
Referensi
sumber
Jika Anda belum mengonfigurasi waktu tunggu dalam kode Anda, Ini akan menjadi waktu tunggu permintaan default di browser Anda.
1) Firefox - 90 detik
Ketik
about:config
di bidang URL Firefox. Temukan nilai yang sesuai dengan kuncinetwork.http.connection-timeout
2) Chrome - 300 detik
Sumber
sumber
fetchTimeout (url,options,timeout=3000) { return new Promise( (resolve, reject) => { fetch(url, options) .then(resolve,reject) setTimeout(reject,timeout); }) }
sumber
Menggunakan c-promise2 lib, pengambilan yang dapat dibatalkan dengan waktu tunggu mungkin terlihat seperti ini ( Demo jsfiddle langsung ):
import CPromise from "c-promise2"; // npm package function fetchWithTimeout(url, {timeout, ...fetchOptions}= {}) { return new CPromise((resolve, reject, {signal}) => { fetch(url, {...fetchOptions, signal}).then(resolve, reject) }, timeout) } const chain = fetchWithTimeout("https://run.mocky.io/v3/753aa609-65ae-4109-8f83-9cfe365290f0?mocky-delay=10s", {timeout: 5000}) .then(request=> console.log('done')); // chain.cancel(); - to abort the request before the timeout
Kode ini sebagai paket npm cp-fetch
sumber