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 pleted. If those calls have pleted, the script finishes and returns the value. A sort of backup timeout that returns an acceptable (if inplete) value instead of timing out pletely 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.
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 pleted. If those calls have pleted, the script finishes and returns the value. A sort of backup timeout that returns an acceptable (if inplete) value instead of timing out pletely 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.
Share Improve this question edited May 7, 2019 at 20:51 Randy Hall asked May 7, 2019 at 20:22 Randy HallRandy Hall 8,21721 gold badges84 silver badges173 bronze badges 2- It may help if you included a bit more detail on the function that you want to call asynchronously with a timeout. – ctt Commented May 7, 2019 at 20:28
-
@ctt this function (
myFunction
) is the one being called. What it's doing internally is probably irrelevant, but it's just a few https calls and a bunch of logic around them that sometimes takes too long. – Randy Hall Commented May 7, 2019 at 20:37
2 Answers
Reset to default 4If 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))
Check execution here
The setTimeout doesn't actually actually works just like the node js event loop does.
With your implementation above, the callback within setTimeout
will never be called because clearTimeout
will be executed almost immediately. The setTimeout while counting down will allow the execution of subsequent code within the script which means clearTimeout
will be called immediately because scripttimmer
variable is truthy.
Another thing to note is you, should only use clearTimeout
if you plan on disrupting the setTimeout
from executing its callback.
You could try an implementation with a callback which will allow you to interact with your return variable like so:
const myFunction = async callback => {
var scripttimer = setTimeout(function(){
callback("my value");
}, 3000);
return "did this anyways";
}
myFunction(val => console.log(val));
See execution here
Also, you should avoid using async
unless you're planning on using an await
within your function.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745555714a4632807.html
评论列表(0条)