Reputation: 12424
I got a JS code that simply activates a method. This method invokes an HTTP request which is causing some remote process to begin. I then need to check every 5 seconds if the remote process ended with a timeout of 5 minutes, after which I need to stop the waiting and throw an error if the timeout had expired, otherwise I need to simply log the result and complete the method.
What I'm not sure is how do I stop the execution of the main method until I get the response so I can have a value to log. This is what I got so far:
(async function(param)
{
...
var res = await fetch(...); //activate the remote proccess
var textAnswer = await res.text();
var infoObj = JSON.parse(textAnswer);
startChecks(infoObj.info.id); // this is the method which I need to await on somehow
}("paramValue");
async function startChecks(id)
{
var startTime = new Date().getTime();
intervalId = setInterval(checkStatus, 5000, id, startTime);
}
async function checkStatus(id, startTime)
{
//if more than 5 minutes had passed
if(new Date().getTime() - startTime > 300000)
{
clearInterval(intervalId);
throw new Error("External pipeline timeout expired");
}
var res = await fetch(...); //check remote process
var ans = await res.text();
var obj = JSON.parse(ans);
if(obj.finished) clearInterval(intervalId);
}
Like I said, what I want to achieve is that my main function won't end until all intervals are done with either the error thrown or the process finishes. How can I achieve that?
Upvotes: 0
Views: 340
Reputation: 40852
You would create a helper function that executes your function in given intervals until it resolves to something different than undefined
. But only for the maximum amount of time.
This could look something like this:
// helper to wait for time milliseconds
async function sleep(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
async function repeatedExecution(callback, interval, timeout) {
// get start time
const start = Date.now();
// repeat as long the start time + timout is larger then the current time
while (start + timeout > Date.now()) {
// get a promise that resolves in interval seconds
let sleeper = sleep(interval)
// execute the callback
let res
if (res = await callback()) {
// if the callback returns something truthy return it
return res;
}
// wait until time for interval ends and then continue the loop
await sleeper;
}
// if we reach this point we timed out
throw new Error('timed out');
}
async function run() {
/*
var res = await fetch(...); //activate the remote proccess
var textAnswer = await res.text();
var infoObj = JSON.parse(textAnswer);
*/
try {
let result = await repeatedExecution(() => {
/*
var res = await fetch(...); //check remote process
var ans = await res.text();
var obj = JSON.parse(ans);
if(obj.finished) {
return true
}
*/
}, 1000, 3000);
// do something on success
} catch (err) {
// handle the error (timeout case)
console.error(err)
}
}
run();
Upvotes: 1