完全清楚,如果有问题,我将在Node中进行此操作。
我有一个方法可以进行几个同步调用(它们依赖于下一个调用的反馈,因此必须是同步的),而且我对环境或正在调用的东西没有太多控制。
我需要在设置的时间(约3秒)后返回一个值,无论这些调用是否完成。如果这些调用已完成,脚本将结束并返回值。一种备份超时,它返回可接受的值(如果不完整),而不是由于服务器执行限制和引发错误而完全超时。
我立即想到使用setTimeout()
(如果没有跳闸,则使用clearTimeout()
)来返回。但是,在setTimeout回调中返回一个值并不会结束我的脚本并返回该值,显然-那么我该怎么办?
//"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";
}
尝试
应该尝试进行try-catch-throw设置:
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";
}
...但是catch不能捕获它,这有点有意义,因为抛出的错误在try-catch的范围之外,因为它是异步的...所以到目前为止,我有个最好的主意。
答案 0 :(得分:1)
setTimeout实际上不像node js事件循环那样实际工作。
在上述实现中,setTimeout
中的回调将永远不会被调用,因为clearTimeout
几乎会立即执行。 setTimeout在递减计数时将允许在脚本中执行后续代码,这意味着clearTimeout
将立即被调用,因为scripttimmer
变量是正确的。
要注意的另一件事是,如果您打算中断clearTimeout
的执行其回调,则应仅使用setTimeout
。
您可以尝试通过回调实现,这样您就可以与返回变量进行交互了:
const myFunction = async callback => {
var scripttimer = setTimeout(function(){
callback("my value");
}, 3000);
return "did this anyways";
}
myFunction(val => console.log(val));
查看执行情况here
此外,除非打算在函数中使用async
,否则应避免使用await
。
答案 1 :(得分:1)
如果将httpCall
函数中的延迟更改为少于3秒,则输出将为hello
如果httpCall
中的延迟超过3秒,那么您将获得输出为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))