【问题标题】:Force JavaScript setTimout function to run after x miliseconds强制 JavaScript setTimeout 函数在 x 毫秒后运行
【发布时间】:2019-07-08 21:37:37
【问题描述】:

我正在尝试创建一个超时函数,该函数会在函数挂起时间过长时引发错误。

我有以下代码:

function go() {

  try{
    console.log('started, timeout in 2 seconds...');
    setTimeout(()=>{
      throw new Error('Timed Out!');
    }, 2000);

    while(true){
      //will run forever
    }
  }catch (e) {
    console.log('timeout function worked!');
  }
}

go();

但是,永远不会抛出错误。我认为这是因为事件循环在 JS 中的工作方式,但我希望我的超时函数在 2 秒后执行,无论发生什么其他事情。我如何做到这一点?

【问题讨论】:

标签: javascript loops events timeout


【解决方案1】:

我希望我的超时功能在 2 秒后执行,无论发生什么其他事情。我如何做到这一点?

你真的不能。正如您所怀疑的,该问题与事件循环有关。只有一个线程可供您使用,并且您已将其置于无限循环中。由于您永远不会返回,因此事件循环没有机会运行 setTimeout 指定的函数。

如果您希望 while 循环停止,您的 while 循环必须是停止它的循环。也许是这样的:

const before = Date.now();
while (true) {
  // do stuff
  if (Date.now() - before > 2000) {
    throw new Error('Timed Out!');
  }
}

【讨论】:

  • 在我的实际应用程序中,该函数挂在 http: 请求上,而不是像这种情况下的 while 循环。在我的实际应用程序中是否可以强制执行?我对 JS 还是很陌生,但似乎 http 请求的处理方式与常规事件循环不同。非常感谢您的帮助!
  • 除非您使用同步 http 请求(您不应该这样做),否则它不会阻塞线程。超时将在大约 2 秒后消失,假设此时没有任何线程挂起。
  • 您可能想针对您的真实场景提出一个新问题。我们为您发布的答案提供了答案,这似乎与您的实际情况无关。
【解决方案2】:

我认为这是因为您首先进入无限循环并且永远不会退出,因此您的 settimeout 永远不会触发。

我不知道您要达到什么目的,但是如果您想抛出错误,请将 while 循环移到最后的 settimeout 内。 顺便说一句,没有意义

【讨论】:

    【解决方案3】:

    setTimeout() 不像你想象的那样工作。直到 while 循环运行。不会调用setTimeout() 函数。

    Javascript 不支持多线程,因为它是一种解释性语言。 多线程:是一种允许多线程存在的执行模型。See more

    下面是例子。

    function loop(){
      console.time('time');
      for(let i = 0;i<10000000;i++){
        if(i % 2000000 === 0) console.log("I am looping");
      }
      console.timeEnd('time');
      console.log("Loop finished");
    }
    loop();
    setTimeout(() => {
      console.log("I am logged from setTimeout")
    },0)

    【讨论】:

      【解决方案4】:

      如果事件循环无法继续,您将无能为力。但是,下面的代码应该更接近您正在寻找的内容。如果你需要做一个while语句,把代码往下做。

      function go() {
        try{
          var timeout = setTimeout(()=>{
            throw new Error('Timed Out!');
          }, 2000);
      
          //do stuff; it can't hog the event loop
        }catch(e){
          
        }
        clearTimeout(timeout);
        return true; //return value
      }
      
      go();
      var iterations = 0;
      while(condition && iterations < 10){
        //do stuff
        iterations++;
      }
      

      【讨论】:

      • @NicholasTower 的 while 语句更好,但您 (@BSweeze) 似乎没有提出您需要提出的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 2019-03-20
      • 2020-04-29
      相关资源
      最近更新 更多