I have an await function() which waits for an external API. Usually, these APIs take 600ms to return data. But sometimes it's taking around 10 seconds. So how do I write a function so that if it takes more than 1 second, then break that function and resolve anyway (don’t wait for the API)
Here's the main function code which calls the API.
console.log("Before Await");
await fetchExternalAPI("data");
console.log("Continue if success or takes more than x seconds");
The actual function:
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
}
}
I want to return success fo the above function
- if fetch is success
- or if exceeded more than x seconds
Both should return success no matter the real output.
CodePudding user response:
You can use AbortController
to abort
the fetch method, inside a setTimeout
with 1sec, and if the fetch
resolved before the setTimeout
callback execute, then 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
}
}
CodePudding user response:
I think you need to use Axios.
npm i axios
than in body you have one property timeout.
const instance = await axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
CodePudding user response:
You can add a promise in your call to resolve on time and reject if too long. The following code has not been tested but that's the 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
}
}