博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
requestAnimationFrame与setTimeout的定时器
阅读量:5745 次
发布时间:2019-06-18

本文共 1266 字,大约阅读时间需要 4 分钟。

之前参加网易游戏笔试时,第一道大题就是问的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

你可能感兴趣的文章