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?
El uso de una solución de carrera prometedora dejará la solicitud suspendida y seguirá consumiendo ancho de banda en segundo plano y reducirá la solicitud simultánea máxima permitida mientras aún está en proceso.
En su lugar, use AbortController para abortar la solicitud. Aquí hay un ejemplo
const controller = new AbortController() // 5 second timeout: const timeoutId = setTimeout(() => controller.abort(), 5000) fetch(url, { signal: controller.signal }).then(response => { // completed request before timeout fired // If you only wanted to timeout the request, not the response, add: // clearTimeout(timeoutId) })AbortController también se puede usar para otras cosas, no solo para buscar, sino también para flujos de lectura/escritura. Las funciones más nuevas (especialmente las basadas en promesas) usarán esto cada vez más. NodeJS también ha implementado AbortController en sus flujos/sistema de archivos. Sé que el bluetooth web también lo está investigando. Ahora también se puede usar con la opción addEventListener y hacer que deje de escuchar cuando finalice la señal
Edite si desea una solución aún más limpia que maneje todos los casos extremos, busque esta respuesta: https://stackoverflow.com/a/57888548/1059828 .
Realmente me gusta el enfoque limpio de esta esencia 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) ) ]); }principal.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 })Como se señaló en los comentarios, el código en la respuesta original sigue ejecutando el temporizador incluso después de que se resuelve/rechaza la promesa.
El siguiente código soluciona ese problema.
function timeout(ms, promise) { return new Promise((resolve, reject) => { const timer = setTimeout(() => { reject(new Error('TIMEOUT')) }, ms) promise .then(value => { clearTimeout(timer) resolve(value) }) .catch(reason => { clearTimeout(timer) reject(reason) }) }) }No tiene un valor predeterminado especificado; la especificación no discute los tiempos de espera en absoluto.
Puede implementar su propia envoltura de tiempo de espera para 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 de https://github.com/mislav