我有一个函数可以执行一些HTTP requests
,如果触发了某个条件,我需要每隔一定时间(在本例中为5秒(执行一次。
发生的情况是,有时setInterval
循环中的请求花费的时间超过了指定的时间,并且循环再次触发,再次调用请求,而不等待前一个请求得到解决。
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();
我已经尝试过做一个递归的setTimeOut函数,就像在这篇文章中一样,它工作了,但几次请求后它就停止了工作,不是因为发生了stack overflow
,而是因为它简单地停止了!请求已经完成,但它从未返回响应,因此代码停止。在它停下来之前的几次,它变得很慢。
我也已经尝试过在while循环中使用setTimeOut,但循环似乎不等待间隔,而不是在这个异步上下文中。
所以我需要的解决方案是:一种每5秒处理一次请求的方法,但如果返回响应需要更多的时间,请等待。
好吧,这里有一个解决方案,可以让周期尽可能规律。只要响应在5秒的超时时间内到达,周期轮询就应该非常有规律。但是,如果响应来得晚,则会立即发出新请求并进行处理。
我还添加了一个try-catch块,因为它很可能在HTTP请求中出现一些错误(也因为你正在做其他事情(。这会让你决定在这种情况下该如何行事。
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();