Reputation: 167
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
Reputation: 17616
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.
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.
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.
*
to your function nameyield
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
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