Javascript 基于web的计时器

Javascript 基于web的计时器,javascript,Javascript,是否有必要在浏览器中创建一个变速计时器,以便为所有操作系统和浏览器提供完全相同的结果?如果我想要每个用户每分钟140次,不管他们的计算机速度如何 我一直在使用javascript setTimeout()和setInterval(),但我认为它们取决于计算机的速度和程序中的代码量。 如何将系统时钟合并到浏览器中?或者任何其他想法?您可以使用的最佳方法是setInterval(),或者尝试从Date()中派生一些东西 请注意,时间并不精确,我认为这是因为JavaScript的单线程性质。函数set

是否有必要在浏览器中创建一个变速计时器,以便为所有操作系统和浏览器提供完全相同的结果?如果我想要每个用户每分钟140次,不管他们的计算机速度如何

我一直在使用javascript setTimeout()和setInterval(),但我认为它们取决于计算机的速度和程序中的代码量。
如何将系统时钟合并到浏览器中?或者任何其他想法?

您可以使用的最佳方法是
setInterval()
,或者尝试从
Date()
中派生一些东西

请注意,时间并不精确,我认为这是因为JavaScript的单线程性质。

函数
setTimeout()
setInterval()
几乎是最好的。这些函数的超时参数以毫秒为单位指定,不依赖于运行浏览器的计算机的总体速度


但是,这些函数肯定不是硬实时函数,如果浏览器在超时或间隔过期时正忙于执行其他操作,则在实际调用回调函数之前可能会有一点延迟。

您必须在解决方案中使用
setTimeout
setInterval
,但由于以下原因,它将不准确:

  • 浏览器有一个最小超时,它不是0毫秒。跨浏览器的最小值约为14毫秒
  • 计时器是不精确的。它们表示排队时间,而不是执行时间。如果计时器启动时正在执行其他操作,则代码将被推送到队列等待,并且可能要过很久才能真正执行
  • 您可能希望使用
    setTimeout
    以及手动跟踪当前时间(使用
    Date
    )来逐步执行程序。对于您的情况,请尝试以下方法:

    function someAction(delta) {
      // ...
    }
    
    function beat() {
      var currentTime = +new Date;
      var delta = currentTime - pastTime;
    
      if (delta > 430) { // 430ms ~ 140bpm
       pastTime = currentTime;
       someAction();
      }
    
      setTimeout(beat, 107); // 4x resolution
    }
    
    var pastTime = +new Date;
    beat();
    

    这应该大约为每分钟140次,使用更高的分辨率以避免更大的延迟。不过,这只是一个示例,您可能需要进行更多的工作,以使其为您的应用程序实现最佳性能。

    您是否有任何参考或测试支持setTimeout不准确的说法?它一直对我有效(尽管我没有在最后几毫秒验证它)。(来自@gravityboy)感谢ben,这是一个很好的答案。它执行setimeout 4次,然后beat()只会在超过阈值时调用someaction(),对吗?如果在阈值430前几毫秒调用它会发生什么?那么它在再次等待107超时之前不会有再次开火的机会?你认为setTimeout中可以使用的最小数字是多少?(来自@gravityboy继续)还有,你认为没有setTimeout的循环,只是使用。。。var currentTime=+新日期;var delta=当前时间-过去时间;它将以计算机允许的任何速度运行和检查delta?事实上,当增量超过时,数百次调用该函数。那是一个失控的环路吗?p、 我认为=+新日期是一个输入错误,但事实并非如此。它以毫秒为单位显示日期?我甚至在任何地方都找不到记录。是的,你是对的,这可能会导致100毫秒的延迟。这只是在应用程序响应性和计时器准确性方面的折衷。如果您使用0毫秒设置超时,它将以浏览器允许的最快速度执行(某些情况下约14毫秒),这将提供最好的分辨率,从而获得最高的精度。但是,这将以牺牲应用程序的其余部分为代价。对于一些简单的应用程序,这应该很有效,但对于复杂的应用程序,这可能不太有效。使用循环的问题是JavaScript是单线程和阻塞的。因此,输入代码循环将锁定浏览器,直到执行完成。所以你不能这么做,否则用户根本不能使用你的应用程序。您所能做的最好的事情就是我向您展示的
    setTimeout
    循环,超时时间为0毫秒。至于
    +新日期
    ,这只是以毫秒为单位获取当前时间的最少代码。它相当于
    (new Date()).getTime()
    ,它由
    函数的
    值调用,该函数在使用
    +
    强制时调用。