requestAnimationFrame与setTimeout的定时器

之前参加网易游戏笔试时,第一道大题就是问的requestAnimationFrame这个API,同时让说明这个API与setTimeout的异同。当时看到的时候完全不知道requestAnimationFrame是什么,直接放弃。想着回来还是得吧这个知识盲点给补上。

setTimeout

setTimeout由浏览器的定时器模块来管理,当达到所设置的定时时间,就会将定时器绑定的事件(函数)加入到宏任务队列中。不同异步任务的执行顺序可参考事件循环任务执行顺序
通过在setTimeout绑定的函数中再绑定一个setTimeout来模拟setInterval定时器,如下代码所示,这样的好处是避免动画的抖动,保证下一次动画函数执行必须在当前动画执行结束后的再执行。

var i = 0;
var timer;
var foo = function() {
    console.log(i++);
    timer = setTimeout(foo, 1000)
}
foo();

但是,setTimeout并不能按照设置的定时准时触发,这点可以从js事件循环来解释。当设置了该定时器时,假设定时1000毫秒,

  • 首先,绑定函数交由定时器模块处理;
  • 然后,当到达1000毫秒时,定时器模块会将该绑定事件加入到任务队列中,注意,这个时候已经到了我们的预设时间了,但是实际上函数并没有被执行。
  • 最后,当任务队列中优先于该任务的函数执行完成后,才会执行该定时器绑定的函数。所以这里的实际执行的时间相比预设时间会更晚。

requestAnimationFrame

requestAnimationFrame和屏幕刷新是同步的,也就是说屏幕每刷新一次,requestAnimationFrame就触发一次。
由于requestAnimationFrame与浏览器刷新同步,因此不会像setTimeout那样积累时间上的误差。加入屏幕刷新率是60,则最小间隔时间是16.67ms。

var i = 0;
var timer;
var foo = function() {
    console.log(i++);
    timer = setTimeout(foo, 1000)
}
foo();

由于不同显示器的刷新率不同,因此如果要定时的话,时间也不相同。可以通过js来计算屏幕刷新率。

var refreshInterval;
(function(){
    var i = 0;
    var foo = function() {
        if (++i == 100) {
            refreshInterval = (new Date().getTime() - time1)/100;
            return;
        }
    }
    var time1 = new Date().getTime();
    foo();
}())

转载于:https://www.cnblogs.com/ykli/p/9674269.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值