如果执行时间太长,则跳过该功能。的JavaScript

时间:2019-01-23 12:47:23

标签: javascript asynchronous functional-programming

如果执行时间过长,如何跳过功能。

例如,我有3个功能:

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

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

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

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

因此,例如由于某种原因,函数B内部具有无限循环,并保持运行。如果功能B执行时间过长,如何跳过功能B并转到功能C?

我尝试了这个,但似乎不起作用:

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

但似乎不起作用。


更新1:仅供参考,我没有做任何反模式,但NPM中的功能B属于我,所以我向仓库​​的所有者提交了问题。试着躲开子弹,以便在修复之前我有一些额外的时间。谢谢你们到目前为止对我的帮助:)

2 个答案:

答案 0 :(得分:2)

为了知道一个函数需要花费多少时间,您需要执行并测量。阅读about the Halting Problem。图灵从根本上证明了停止问题是无法解决的,这意味着没有编程的方法可以确定循环是否是无限的,或更笼统地说,是确定执行是否会停止。

问题在于,即使在时间上为函数执行设置了阈值,也无法从外部终止函数。这样,一旦您进入无限循环,就无法终止它,除非您的函数内部假定它可以进入无限循环,从而测量其自身的执行时间,并在超过该时间时终止。即使采用这种方法,您也不会节省执行时间,因为所有功能仍将执行,并且其中一些功能将在超过所提供的阈值后立即终止。当然,这还假定您执行的所有方法都是由您编写的,并且要牢记假设,并且不使用任何外部方法。

答案 1 :(得分:2)

setTimeout不能用于停止执行函数

setTimeout不能用于取消功能的执行。 setTimeout只是调用函数之前的延迟。简而言之,是的,您可以在执行之前将其停止,但是一旦执行就无法停止。

通过检查经过的时间来暂停(不推荐)。

一种解决方案是通过在函数中的各处放置检查来检查函数花费了多少时间。

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

但这不能解决您的问题,因此不建议这样做,因为它要求您在关键点上添加许多“检查”,这些关键点可能会使函数在执行过程中花费的时间过长。

使用函数生成器暂停

这是假设您处于同步环境中

函数生成器不是一个完美的解决方案,但它是一个更好的解决方案。

它需要对原始功能进行两个易于理解的修改。

  1. 在您的函数名称中添加*
  2. 在功能的关键位置添加yield关键字,这可能被认为是“执行时间长”

最后,将您要测试的函数传递给某些包装器,例如下面提供的run方法。

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