【问题标题】:Javascript setTimeout doesn't allow interval under 100 millisecondsJavascript setTimeout 不允许低于 100 毫秒的间隔
【发布时间】:2012-01-17 03:13:59
【问题描述】:

我想每 10 毫秒触发一次递归函数,但 setTimeout 似乎没有任何低于 100 的值,无论我放什么。

decrementCountdown = function() {
    console.log('fired');
    t = setTimeout("decrementCountdown()", 100);
}

为什么我不能设置小于 1000 毫秒的值?

编辑: 看起来我的计时器正在正确触发......问题是当我使用它来调用函数时(如 Jquery 的 html() )。即使 setTimeout 以正确的时间间隔调用该函数,它的触发速度也不会超过 100 毫秒。

有人知道如何在我的页面上设置一个倒计时 10 毫秒的计时器吗?

【问题讨论】:

  • 是什么让你认为它不是?你的例子并不能证明什么。
  • 因为无论我输入 999 还是 1,它都会以完全相同的速率触发……1 秒。这是一个简化的例子,我的真实代码使用这个函数来减少倒数计时器。如果我把它包括在内会更有帮助吗?

标签: javascript timer


【解决方案1】:

一个更好的例子是:

var stop = 0;
decrementCountdown = function() {
    console.log(new Date().getTime());
    stop++;
    if (stop<10) t = setTimeout("decrementCountdown()", 100);
}

decrementCountdown();

如您所见,超时大约每 100 毫秒触发一次 (jsFiddle)。

【讨论】:

    【解决方案2】:

    我试过你的例子,它似乎工作正常。

    为了它的价值,我会通过使用来节省 setTimeout 的不断重新声明

    function decrementCountdown()
    {
        /*Do your thing*/
    }
    setInterval(decrementCountdown, 100);
    

    【讨论】:

      【解决方案3】:

      这里有一个page you can run,它将准确地告诉您系统浏览器中setTimeout() 的变化。它运行 10,000 次 setTimeout(fn, 1) 操作并记录调用之间的平均、最大和最小延迟并将其输出到屏幕。

      setTimeout() 确实有一个可以接受的最小值。它因浏览器而有所不同,但通常在 10-20 毫秒的范围内(尽管它可以更小或更大 - 这取决于浏览器)。这称为“夹紧”。其目的是保护浏览器事件队列免受过多的 javascript 执行和没有足够的时间来做其他事情(如服务其他用户事件、重绘等)。

      但是,这仅意味着浏览器不会比最小值更快地触发一个,并不意味着您总是会那么快得到一个。 Javascript 是单线程的,所以如果浏览器很忙,setTimeout() 不会发生,直到没有更多的 javascript 执行并且下一个计时器事件到达队列的前面。

      此外,当带有计时器的页面不是当前选项卡时,某些现代浏览器中的计时器会变慢。您可以在上面的页面中通过在运行时切换到另一个选项卡来看到这一点,并看到您的平均时间变慢了。

      对于那些好奇的人,这里是该页面的代码:

      var lastTime = new Date();
      var cumDiff = 0;
      var minDelta = 1000000;
      var maxDelta = 0;
      var cnt = 0;
      var nowElem = document.getElementById("now");
      var deltaElem = document.getElementById("delta");
      var minDeltaElem = document.getElementById("minDelta");
      var maxDeltaElem = document.getElementById("maxDelta");
      function run() {
          var now = new Date().getTime();
          var diff = now - lastTime;
          cumDiff += diff;
          minDelta = Math.min(diff, minDelta);
          maxDelta = Math.max(diff, maxDelta);
          cnt++;
          var avgDelta = cumDiff / cnt;
          lastTime = now;
          nowElem.innerHTML = now;
          deltaElem.innerHTML = avgDelta.toFixed(1);
          minDeltaElem.innerHTML = minDelta;
          maxDeltaElem.innerHTML = maxDelta;
          if (cnt < 10000) {
              setTimeout(run, 1);
          }
      }
      setTimeout(run, 1);
      

      免责声明:一些较旧的浏览器没有非常准确的Date() 函数(仅精确到 10-20 毫秒内),因此这些数据在其中一个较旧的浏览器中不会非常准确。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-03
        • 1970-01-01
        • 1970-01-01
        • 2019-01-19
        • 2023-03-04
        相关资源
        最近更新 更多