my-blog icon indicating copy to clipboard operation
my-blog copied to clipboard

专题1: setInterval有什么弊端

Open luoxue-victor opened this issue 5 years ago • 3 comments

今日专题:setInterval有什么弊端?

这个题目有很多人懂,但是又很多人不懂,这个专题就是让你彻底弄透 setInterval

luoxue-victor avatar Nov 08 '19 00:11 luoxue-victor

eventloop在Node环境和浏览器环境的表现有细微的不一致

dawnxuuu avatar Nov 08 '19 01:11 dawnxuuu

弊端

  1. setInterval 对自己调用的代码是否报错漠不关心。即使调用的代码报错了,它依然会持续的调用下去
  2. setInterval 无视网络延迟。在使用 ajax 轮询服务器是否有新数据时,必定会有一些人会使用setInterval,然而无论网络状况如何,它都会去一遍又一遍的发送请求,如果网络状况不良,一个请求发出,还没有返回结果,它会坚持不懈的继续发送请求,最后导致的结果就是请求堆积。
  3. setInterval 并不定时。如果它调用的代码执行的时间小于定时的时间,它会跳过调用,这就导致无法按照你需要的执行次数或无法得到你想要的结果。
  4. setInterval 做动画时低频会有卡顿现象,尤其是在低端机型使用

解决方案

  1. 使用 setTimeout 代替 setInterval
  2. 可以给 setTimeout 设置时间后,在最后调用自身。如果希望“匀速”触发。可以计算代码执行时间,用希望的延迟减去上次执行的时间。
  3. 可以使用 requestAnimationFrame 代替

注:有一种想法是将 setInterval 的延迟时间设置的长于上述的几种时间,来达到绝对的均速调用。但事实上,js的计时器因为自身机制的原因,存在4ms–15ms的误差。

参考文章:

https://blog.csdn.net/runonway/article/details/80900437 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame

解释第三点

  1. 标准中,setInterval() 如果前一次代码没有执行完,则会跳过此次代码的执行。
  2. 浏览器中,setInterval() 如果前一次代码没有执行完,不会跳过此次代码,而是将其插在队列中,等待前一次代码执行完后立即执行。
  3. Node中,setInterval()会严格按照间隔时间执行。

https://www.jianshu.com/p/0ad05e325f9b

luoxue-victor avatar Nov 08 '19 01:11 luoxue-victor

  1. setInterval 做动画时低频会有卡顿现象,尤其是在低端机型使用,可以使用 requestAnimationFrame 代替

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行

MDN: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame

luoxue-victor avatar Nov 08 '19 02:11 luoxue-victor