J'ai une demande fetch-api
POST
:
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
Je veux savoir quel est le délai d'attente par défaut pour cela? et comment pouvons-nous lui attribuer une valeur particulière telle que 3 secondes ou des secondes indéfinies?
Il n'a pas de valeur par défaut spécifiée. la spécification ne discute pas du tout des délais.
Vous pouvez implémenter votre propre wrapper timeout pour les promesses en général:
// Rough implementation. Untested.
function timeout(ms, promise) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error("timeout"))
}, ms)
promise.then(resolve, reject)
})
}
timeout(1000, fetch('/hello')).then(function(response) {
// process response
}).catch(function(error) {
// might be a timeout error
})
Comme décrit dans https://github.com/github/fetch/issues/175 Commentaire de https://github.com/mislav
J'aime vraiment l'approche propre de cette Gist using 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
})
En utilisant la syntaxe d'abandon, vous pourrez faire:
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);
})
Voir AbortController page sur MDN.
il n'y a pas encore de prise en charge de délai d'attente dans l'API d'extraction. Mais cela pourrait être réalisé en l'enveloppant dans une promesse.
pour par exemple.
function fetchWrapper(url, options, timeout) {
return new Promise((resolve, reject) => {
fetch(url, options).then(resolve).catch(reject);
if (timeout) {
const e = new Error("Connection timed out");
setTimeout(reject, timeout, e);
}
});
}
EDIT: la demande d'extraction sera toujours exécutée en arrière-plan et enregistrera probablement une erreur dans votre console.
En effet, l’approche Promise.race est meilleure.
Voir ce lien pour référence Promise.race ()
Course signifie que toutes les promesses seront exécutées en même temps et la course s'arrêtera dès qu'une des promesses retournera une valeur . Par conséquent, une seule valeur sera renvoyée . passe une fonction à appeler si le délai de récupération est dépassé.
fetchWithTimeout(url, {
method: 'POST',
body: formData,
credentials: 'include',
}, 5000, () => { /* do stuff here */ });
Si cela vous intéresse, une implémentation possible serait:
function fetchWithTimeout(url, options, delay, onTimeout) {
const timer = new Promise((resolve) => {
setTimeout(resolve, delay, {
timeout: true,
});
});
return Promise.race([
fetch(path, request),
timer
]).then(response) {
if (response.timeout) {
onTimeout();
}
return response;
}
}
Vous pouvez créer un wrapper timeoutPromise
function timeoutPromise(timeout, err, promise) {
return new Promise(function(resolve,reject) {
promise.then(resolve,reject);
setTimeout(reject.bind(null,err), timeout);
});
}
Vous pouvez ensuite envelopper toute promesse
timeoutPromise(100, new Error('Timed Out!'), fetcn(...))
.then(...)
.catch(...)
Cela n'annulera pas réellement une connexion sous-jacente mais vous permettra de temporiser une promesse.
Référence
fetchTimeout (url,options,timeout=3000) {
return new Promise( (resolve, reject) => {
fetch(url, options)
.then(resolve,reject)
setTimeout(reject,timeout);
})
}