有什么区别吗?
是的。超时在调用 setTimeout() 后执行一定时间;间隔在上一个间隔触发后执行一定时间。
如果您的 doStuff() 函数需要一段时间才能执行,您会注意到差异。例如,如果我们用 来表示对 setTimeout/setInterval 的调用,则使用 和 JavaScript 代码执行的触发,时间线如下所示:.
*
[-----]
Timeout:
. * . * . * . * .
[--] [--] [--] [--]
Interval:
. * * * * * *
[--] [--] [--] [--] [--] [--]
下一个复杂情况是,如果一个间隔触发,而JavaScript已经忙于做某事(例如处理以前的间隔)。在这种情况下,将记住间隔,并在上一个处理程序完成并将控制权返回给浏览器后立即发生。例如,对于有时很短([-])有时很长([-])的doStuff()进程([-----]):
. * * • * • * *
[-] [-----][-][-----][-][-] [-]
• 表示无法立即执行其代码的间隔触发,而是将其设置为挂起。
因此,间隔时间试图“赶上”以按计划返回。但是,它们不会将一个队列在彼此之上:每个间隔只能有一个执行挂起。(如果它们都排队,浏览器将留下一个不断扩大的未完成执行列表!
. * • • x • • x
[------][------][------][------]
x 表示无法执行或挂起的间隔触发,因此被丢弃。
如果您的 doStuff() 函数习惯性地执行时间长于为其设置的时间间隔,则浏览器将占用 100% 的 CPU 来尝试为其提供服务,并且可能会变得响应速度降低。
你使用哪个,为什么?
链超时为浏览器提供了有保证的空闲时间;间隔尝试确保它正在运行的函数尽可能接近其计划时间执行,但以牺牲浏览器 UI 可用性为代价。
我会考虑一个一次性动画的间隔,我希望尽可能流畅,而链接的超时对于在页面加载时一直发生的正在进行的动画来说更礼貌。对于要求较低的用途(例如每 30 秒触发一次简单的更新程序或其他用途),您可以安全地使用其中任何一个。
在浏览器兼容性方面,setTimeout 早于 setInterval,但您今天遇到的所有浏览器都支持这两种功能。多年来的最后一个流浪者是WinMo<6.5的IE Mobile,但希望现在这也已经过去了。