首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >有比setTimeout更精确的创建Javascript计时器的方法吗?

有比setTimeout更精确的创建Javascript计时器的方法吗?
EN

Stack Overflow用户
提问于 2008-10-12 20:38:36
回答 12查看 39.8K关注 0票数 74

一直困扰我的是Javascript中的setTimeout()方法是多么的不可预测。

根据我的经验,计时器在很多情况下是非常不准确的。所谓不准确,我的意思是实际的延迟时间似乎或多或少变化了250-500ms。虽然这并不是很长的时间,但当使用它来隐藏/显示UI元素时,时间是显而易见的。

有没有什么技巧可以确保setTimeout()的准确执行(不需要求助于外部API),或者这是一个失败的原因?

EN

回答 12

Stack Overflow用户

发布于 2012-03-06 09:52:10

参考:http://www.sitepoint.com/creating-accurate-timers-in-javascript/

这个网站在很大程度上帮助了我。

您可以使用系统时钟来补偿计时器的不准确。如果您将计时函数作为一系列setTimeout调用来运行-每个实例都调用下一个实例-那么为了保持它的准确性,您所要做的就是准确地计算出它到底有多不准确,并从下一次迭代中减去差值:

代码语言:javascript
复制
var start = new Date().getTime(),  
    time = 0,  
    elapsed = '0.0';  
function instance()  
{  
    time += 100;  
    elapsed = Math.floor(time / 100) / 10;  
    if(Math.round(elapsed) == elapsed) { elapsed += '.0'; }  
    document.title = elapsed;  
    var diff = (new Date().getTime() - start) - time;  
    window.setTimeout(instance, (100 - diff));  
}  
window.setTimeout(instance, 100);  

这种方法将最大限度地减少漂移,并将误差降低90%以上。

它解决了我的问题,希望它能有所帮助

票数 34
EN

Stack Overflow用户

发布于 2013-04-19 19:17:51

不久前,我遇到了类似的问题,并提出了一种将requestAnimationFrame与performance.now()相结合的方法,该方法非常有效。

我现在可以让计时器精确到小数点后12位:

代码语言:javascript
复制
    window.performance = window.performance || {};
    performance.now = (function() {
        return performance.now       ||
            performance.mozNow    ||
            performance.msNow     ||
            performance.oNow      ||
            performance.webkitNow ||
                function() {
                    //Doh! Crap browser!
                    return new Date().getTime(); 
                };
        })();

http://jsfiddle.net/CGWGreen/9pg9L/

票数 10
EN

Stack Overflow用户

发布于 2011-09-01 18:36:12

如果您需要在给定的时间间隔内获得准确的回调,以下要点可能会对您有所帮助:

https://gist.github.com/1185904

代码语言:javascript
复制
function interval(duration, fn){
  var _this = this
  this.baseline = undefined
  
  this.run = function(){
    if(_this.baseline === undefined){
      _this.baseline = new Date().getTime()
    }
    fn()
    var end = new Date().getTime()
    _this.baseline += duration
 
    var nextTick = duration - (end - _this.baseline)
    if(nextTick<0){
      nextTick = 0
    }
    
    _this.timer = setTimeout(function(){
      _this.run(end)
    }, nextTick)
  }

  this.stop = function(){
    clearTimeout(_this.timer)
  }
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/196027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档