Tengo una función de espera () que espera una API externa. Por lo general, estas API tardan 600 ms en devolver datos. Pero a veces toma alrededor de 10 segundos. Entonces, ¿cómo escribo una función para que, si demora más de 1 segundo, rompa esa función y resuelva de todos modos (no espere la API)
Aquí está el código de la función principal que llama a la API.
console.log("Before Await"); await fetchExternalAPI("data"); console.log("Continue if success or takes more than x seconds");
La función real:
const fetch = require('node-fetch'); module.exports = async function fetchExternalAPI(data) { try { const response = await fetch("https://www.example.com/api/log", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }); const returnData = await response.json(); console.log("Response: " + JSON.stringify(returnData)) return returnData } catch (e) { console.log("Error: " + e) return e } }
Quiero devolver el éxito de la función anterior.
Ambos deberían devolver el éxito sin importar el resultado real.
Puede usar AbortController
para abort
el método de recuperación, dentro de un setTimeout
con 1 segundo, y si la fetch
se resolvió antes de que se ejecute la devolución de llamada de setTimeout
, entonces clearTimeout
const fetch = require('node-fetch'); module.exports = async function fetchExternalAPI(data) { try { let controller = new AbortController(); let timeId = setTimeout(() => { controller.abort() }, 1000) const response = await fetch("https://www.example.com/api/log", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) signal: controller.signal }); clearTimeout(timeId) const returnData = await response.json(); console.log("Response: " + JSON.stringify(returnData)) return returnData } catch (e) { console.log("Error: " + e) return e } }
Creo que necesitas usar Axios.
npm i axios
que en el cuerpo tiene un tiempo de espera de propiedad.
const instance = await axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} });
Puede agregar una promesa en su llamada para resolver a tiempo y rechazar si es demasiado larga. El siguiente código no ha sido probado pero esa es la idea
const fetch = require('node-fetch'); module.exports = async function fetchExternalAPI(data) { try { const response = await fetch("https://www.example.com/api/log", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }); await new Promise((resolve, reject) => { setTimeout(reject, 50000)); resolve(); }).then(() => { const returnData = await response.json(); console.log("Response: " + JSON.stringify(returnData)) return returnData }).catch(() => { return 'Took too long'; })); } catch (e) { console.log("Error: " + e) return e } }