trungh13
trungh13

Reputation: 167

Skip the function if executing time too long. JavaScript

How can I skip a function if the executing time too long.

For example I have 3 functions :

function A(){
 Do something.. ..
}

function B(){
 Do something.. ..
}

function C(){
 Do something.. ..
}

A();
B();
C();

So for example for some reason function B have infinity loop inside, and keep running. How can I skip function B and go to function C if function B executing too long ?

I tried this but seem not working :

try {
 const setTimer = setTimeOut({ 
  throw new Error("Time out!");
 },500);
 B();
 clearInterval(setTimer);
}
catch(error){
 console.warn(error);
}

But seem not working.


Update 1 : FYI, I didn't do any anti-pattern but function B is something in NPM and I submitted issues to the owner of repo. Just try to dodge the bullet so I have some extra times until the fix. Thanks guys for helping me so far :)

Upvotes: 10

Views: 5529

Answers (2)

kockburn
kockburn

Reputation: 17616

setTimeout cannot be used to halt the execution of a function

setTimeout cannot be used to cancel the execution of a function. setTimeout is simply a delay before your function is called. Which simply means, yes you can stop it before it's executed but once it's executed you can't.

Halt by checking the time lapsed (not recommended).

A solution would be to check how much time the function is taking by placing checks a bit everywhere in your function.

function A(mili){
  const end = Date.now() + mili;
  for(let i = 0; i < 10000; i++){
    for(let j = 0; j < 10000; j++){
      if(Date.now() > end){
        console.log(mili + ": Halting A...");
        return;
      }
    }
  }
  
}

A(100); //halted
A(1000); //halted
A(10000); //passed

But this doesn't solve your problem and is not recommended because it requires you to add many "checks" at key points where your function may be taking time too long during execution.

Halt by using function generators

This is assuming you're in a synchronous environement

Function generators is not a perfect solution but it is a better solution.

It requires two easy to understand modifications of your original function.

  1. Add * to your function name
  2. Add yield keyword in key spots in your function that may be deemed "long execution time"

Finally, pass the function you wish to test in some wrapper like the run method provided below.

function* A(){
  for(let i = 0; i < 10000; i++){
    for(let j = 0; j < 1000; j++){
       yield;
    }
  }
  return "some final value";
}

function run(gen, mili){
  const iter = gen();
  const end = Date.now() + mili;
  do {
    const {value,done} = iter.next();
    if(done) return value;
    if(end < Date.now()){
      console.log("Halted function, took longer than " + mili + " miliseconds");
      return null;
    }
  }while(true);
}

console.log("Running...");
const res1 = run(A, 1000);
const res2 = run(A, 5000);
const res3 = run(A, 100);

console.log("run(A,1000) = " + res1); //halted
console.log("run(A,5000) = " + res2); //passed
console.log("run(A,100) = " + res3); //halted

Upvotes: 6

Konstantin Dinev
Konstantin Dinev

Reputation: 34905

In order to know how much time a function takes to execute, you need to execute it and measure. Read about the Halting Problem. Turing basically proves the halting problem unsolvable, which means that there's no programmatic way of determining whether a loop is infinite, or more generally, whether an execution would ever stop.

The issue is that even if you set a threshold, in terms of time, on your function execution, you cannot terminate your function from outside. This way once you get into the infinite loop, you wouldn't be able to terminate it, unless your function internally assumes it can go into an infinite loop, and thus measures its own execution time and terminates if it surpasses it. Even with such an approach, you wouldn't save execution time, as all of your functions would still execute, and some would just terminate after they surpass the provided threshold. This, of course, also assumes that all of the methods you execute are written by you, with the assumptions in mind, and no external methods are used.

Upvotes: 3

Related Questions