javascript - plugin - twitter share button example
Fetch API request timeout? (7)
Tengo una solicitud
POST
fetch-api
:
fetch(url, {
method: ''POST'',
body: formData,
credentials: ''include''
})
¿Quiero saber cuál es el tiempo de espera predeterminado para esto? ¿Y cómo podemos establecerlo en un valor particular como 3 segundos o segundos indefinidos?
No tiene un valor predeterminado especificado; la especificación no trata los tiempos de espera en absoluto.
Puede implementar su propio contenedor de tiempo de espera para las promesas en general:
// 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
})
Como se describe en https://github.com/github/fetch/issues/175 Comentario por https://github.com/mislav
Puede crear un tiempo de espera
function timeoutPromise(timeout, err, promise) {
return new Promise(function(resolve,reject) {
promise.then(resolve,reject);
setTimeout(reject.bind(null,err), timeout);
});
}
Entonces puedes envolver cualquier promesa
timeoutPromise(100, new Error(''Timed Out!''), fetch(...))
.then(...)
.catch(...)
En realidad, no cancelará una conexión subyacente, pero le permitirá agotar el tiempo de una promesa.
Reference
Realmente me gusta el enfoque limpio de esta gist usando 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
})
Todavía no hay soporte de tiempo de espera en la API de recuperación. Pero podría lograrse envolviéndolo en una promesa.
por ej.
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);
}
});
}
Usando la sintaxis de aborto, podrás hacer:
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);
})
Vea la página de AbortController en MDN.
EDITAR : la solicitud de recuperación aún se ejecutará en segundo plano y probablemente registrará un error en su consola.
De hecho, el enfoque de Promise.race es mejor.
Vea este enlace para referencia Promise.race
Carrera significa que todas las promesas se ejecutarán al mismo tiempo, y la carrera se detendrá tan pronto como una de las promesas devuelva un valor. Por lo tanto, solo se devolverá un valor . También puede pasar una función para llamar si el tiempo de espera se agota.
fetchWithTimeout(url, {
method: ''POST'',
body: formData,
credentials: ''include'',
}, 5000, () => { /* do stuff here */ });
Si esto le interesa, una posible implementación sería:
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;
}
}
fetchTimeout (url,options,timeout=3000) {
return new Promise( (resolve, reject) => {
fetch(url, options)
.then(resolve,reject)
setTimeout(reject,timeout);
})
}