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