【问题标题】:Using setTimeout with intervals less than 1使用间隔小于 1 的 setTimeout
【发布时间】:2013-03-10 00:10:58
【问题描述】:

我在 Javascript 中做了很多递归,为了防止堆栈溢出,我一直在使用 setTimeout。这是一个简单的理论示例:

go(){
    setTimeout(function(){
        x++;
        go();
    },1);
}

我还有一个功能,每隔几秒就将x 记录到控制台,但这不是问题。我所看到的是,无论我为超时输入什么值,我在示例中使用了 1,脚本每秒只能运行 1000 次。我正在做数亿级别的递归,所以这还不够快。当我将超时值设置为 0、0.1 或 1/10 时,我仍然每秒只能获得大约 1000 次。我尝试使用 32 位和 64 位浏览器(Chrome 和 Firefox)无济于事。

我怎样才能将速度提高一个档次?另外,我对这一切都比较陌生,所以如果解决方案是一个简单的解决方案,那就太棒了。

哦,忘了说:如果我完全删除 setTimeout,我每次都会溢出堆栈。

感谢您的帮助!

【问题讨论】:

  • 我想知道您为什么要在客户端浏览器上进行如此繁重的操作。如果您能找到一种在您的服务器上运行它的方法,那就更好了。
  • 我不确定我是否理解;如果您使用 setTimeout 来防止堆栈溢出,那么您一定不需要递归。那么为什么需要 setTimeout 呢?递归变慢只会延迟溢出。
  • 你所做的似乎不对
  • setTimeout 有一个最小超时时间,但如果你的目标是新浏览器,你可以使用 window.postMessage 尽可能快地完成同样的事情。我认为 MDN 有一个例子。 (现在无法在移动设备上发布真正的答案。)
  • 也可以使用自定义事件来执行此操作,包括在旧浏览器上,但我没有尝试过。

标签: javascript settimeout


【解决方案1】:

您的解决方案不在于让您当前的代码运行,而是重新思考代码。

我不知道你是如何在代码中使用递归的,但很明显你用错了。

对于递归的任何合理使用,您都不会溢出堆栈。如果您要进行数亿级别的递归调用,那至少是一百万倍。

使用递归的一种常见方法是将每个级别的工作分成两半。这样一来,您就可以处理所有可以放入内存的项目,而无需深入大约 30 个级别。

【讨论】:

    【解决方案2】:

    我尝试了与您类似的方法并找到了解决方案!您不需要递归和函数setTimeout,但您所需要的只是在for 循环中以1 个间隔在您想要的函数上重复使用setInterval 函数。例如,如果 for 循环重复 10 次,则 10 个计时器将每 4 毫秒执行一次相同的函数。代码会越来越快地重复执行。

    您的代码应如下所示:

    function onload() {
       for (var i = 0; i < 10; i++)
          setInterval(go, 1);
    }
    function go() {
       x++;
    }
    

    【讨论】:

    • 这只是以相同方式做更多工作的一种方式,而且是一种糟糕的方式。您只需在函数中多次执行相同的操作即可获得相同的结果,而且开销更少。
    【解决方案3】:

    JavaScript 是单线程的,setTimeout 会将您的操作放在队列的末尾。即使你减少了延迟,你仍然需要等待之前的操作完成,然后你添加的操作才会启动。

    【讨论】:

      【解决方案4】:

      不可能让 setTimeout 等待少于 4 毫秒。这就是在 HTML 标准(官方规范 here)中定义 setTimeout 的方式。您的问题更有可能与代码的结构有关。向我们展示您的其余代码,也许我们可以帮助解决它。

      【讨论】:

      • 根据您的参考,最小值为 4 毫秒,而不是 1(见注释)
      • 是的,看来你是对的。根据规范,该函数将允许您指定 1 毫秒的延迟,但在内部这会提高到 4 毫秒。固定。
      • 对,你甚至可以指定一个 0 毫秒的延迟 - 这通常被开发人员用来将执行移动到队列的末尾。
      • 你根本不需要包含任何时间参数,它会在最小延迟后运行。
      猜你喜欢
      • 2019-01-19
      • 2023-03-30
      • 2017-01-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      相关资源
      最近更新 更多