Reputation: 37
I have a function that do some HTTP requests
, i need to do them often every certain amount of time (in this case 5 seconds) if a certain condition is triggered.
What happens is that sometimes the requests that are inside the setInterval
loop takes more than the specified time and the loop triggers again, calling the request again, without waiting for the previous to resolve.
function doRequests() {
setInterval(async () => {
//Sometimes the following line takes more than 5 seconds to return its promise
const response = await myRequestFunction();
// do something with response...
if(/*certain condition is triggered*/)
{
//Call the function again
doRequests();
}
}, 5000);
}
doRequests();
I've already tried doing a recursive setTimeOut function like in this post, it worked but a few requests later it simply stopped working, not because a stack overflow
happened but because IT SIMPLY STOPPED! The request was done, but it never brought the response back so the code stopped. And a few time before it stops it got slow.
I've also already tried using a setTimeOut inside a while loop but it seems that loops doesn't wait for intervals, not within this async context.
So the solution i need is: A way to every 5 seconds do the requests, but if it takes more than that to return the response, await for it.
Upvotes: 1
Views: 556
Reputation: 7304
Well, here is a solution in order to keep the cycle period as most regular as possible. As long the responses arrive within the 5s timeout, the cycle polling should be pretty regular. However, if a response comes in late, the new request is made immediately it is processed.
I also added a try-catch block, because it is likely a chance having some error on a HTTP request (and also because you're doing other stuffs in the while). This leads you to decide how to behave in such a cases.
async function doRequests() {
let answered = false;
let expired = false;
//start the timer
let tmr = setTimeout(function() {
if (answered) {
//response already received (and processed), so start a new request
doRequest();
}
else {
//mark the timer as expired
expired = true;
},
5000
);
try {
const response = await myRequestFunction();
// do something with response...
if(/*certain condition is triggered*/)
{
answered = true;
if (expired) {
//Call the function again
doRequests();
}
}
}
catch (err) {
//error trapped: clear timeout
clearTimeout(tmr);
if (/* decide to continue as it was fine */) {
answered = true;
if (expired) {
//Call the function again
doRequests();
}
}
}
}
doRequests();
Upvotes: 1