最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Return for function after certain execution time - Stack Overflow

programmeradmin1浏览0评论

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
Add a ment  | 

2 Answers 2

Reset to default 4

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

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.

发布评论

评论列表(0)

  1. 暂无评论