Full clarity, I'm doing this in Node if that matters.
I have a method that makes a few synchronous calls (they rely on the feedback of each call in the next, so must be synchronous) and I don't have much control over environment or the things I'm calling.
I need to return a value after a set time (about 3 seconds) whether or not those calls have completed. If those calls have completed, the script finishes and returns the value. A sort of backup timeout that returns an acceptable (if incomplete) value instead of timing out completely due to server execution limits and throwing an error.
I immediately think to use a setTimeout()
(and a clearTimeout()
if it's not tripped) to do the return. However, returning a value in the setTimeout callback doesn't end my script and return that value, obviously - so how would I?
//"myFunction" being consumed by something I don't have control over
//Otherwise I'd just wrap the caller in a timeout
myFunction = async () => {
var scripttimer = setTimeout(function(){
//emergency exit - script took longer than 3 seconds
return "I need to return a value for myFunction now";
}, 3000);
//multiple synchronous remote https calls are made
//right here which could sometimes cause this function
//to take more than 3 seconds, at which point the
//scripttimer should kill myFunction by making it return
//a value. That's the part that I'm asking how to do, if
//even possible
if (scripttimer){
//if we took less than 3 seconds, we don't need the backup
//callback in scripttimer and so we're going to kill it
clearTimeout(scripttimer);
}
//best scenario return value, script took less than 3 seconds
return "did this anyways";
}
Tried
Thought to do a try-catch-throw setup:
try {
var scripttimer = setTimeout(function(){
throw "I need to return a value for myFunction now";
}, 3000);
//wait 4 seconds maybe
if (scripttimer){
clearTimeout(scripttimer);
}
return "I don't make it out if I take too long";
} catch (e){
return "acceptable enough";
}
... but the catch doesn't catch it, which kinda makes sense since the error thrown is outside the scope of the try-catch since it's asynchronous... so there goes my best idea so far.
If you change the delay in httpCall
function to less than 3 seconds then you will get the output as hello
and if the delay in httpCall
is more than 3 seconds then you will get the output as bye
// Your Http Call Here which may take 3 seconds or more. eg.5 seconds
function httpCall(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve("hello")
},5000)
});
}
// your main function where you will be calling sync functions
function operation(){
return new Promise((resolve,reject)=>{
const timeoutID = setTimeout(function(){
resolve("bye")
},3000)
httpCall().then(result=>{
clearTimeout(timeoutID)
resolve(result)
})
});
}
// This is how you should call
operation().then((result)=>console.log(result))