在一定的执行时间后返回函数

时间:2019-05-07 20:22:16

标签: javascript node.js return settimeout

完全清楚,如果有问题,我将在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的范围之外,因为它是异步的...所以到目前为止,我有个最好的主意。

2 个答案:

答案 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))

Check execution here