I have a recursive async function getResponse(url,attempts = 0)
, which polls external api for the response and resolves or exits after reaching X number of retries or on a server error.
However, it's internal "clock" is based off the number of retries (after allowing for delays to avoid rate limits), but I also want to have a flexibility in setting a time based timer, which would resolve the function and end the recursion. Ideally, I want to be able to wrap time based timer around my recursive async function, like so timed(getResponse(url),3400)
I have only managed to have both the time based and "retries" based timer working together, by packaging both timers in one async function with local variable expired
serving as an exit flag and setting Promise.race conditions on both functions.
async function timedgetResponse (expiry = 3500,url) {
let expired = false;
async function timeout(expiry){
await new Promise(_=> setTimeout(_,expiry));
expired = true;
return false;
};
async function getResponse(url,attempts = 0){
try {
if(expired){ return false; };
const limit = 10;
if(attempts >= limit){ok: false, e:"MAX_ATTEMPTS"};
const rawRes = await fetch(url,
{
method: 'GET',
credentials: 'include',
headers: {
'Accept': 'application/json'
}
});
if (!rawRes.ok) { throw (Error('SERVER_ERROR')); };
const res = await rawRes.json();
if(!res || res.status === 0){ throw (Error(res.request)); };
return {ok: true, res: res.request};
} catch(e){
const err = e.message;
if(err === "RESPONSE_NOT_READY"){
await new Promise(_ => setTimeout(_, 333));
attempts +=1;
return getResponse(url,attempts);
} else
if(err === "SERVER_ERROR_ON_RESOLVER"){
await new Promise(_ => setTimeout(_, 10000));
attempts +=1;
return getResponse(url,attempts);
} else {
return {ok: false, e:"MISC_ERROR"};
};
};
};
const awaited = await Promise.race([
getResponse(url),
timeout(expiry)
]);
return awaited;
};
I sense that it is not a correct way to do it and would appreciate any help towards timed(getResponse(url),3400)
solution.