Is there any difference? (有什么区别吗?)
Yes. (是。) A Timeout executes a certain amount of time after setTimeout() is called; (调用setTimeout()后,超时执行一定的时间;) an Interval executes a certain amount of time after the previous interval fired. (间隔在上一个间隔触发后执行一定的时间。)
You will notice the difference if your doStuff() function takes a while to execute. (如果doStuff()函数需要一段时间才能执行,您会注意到区别。) For example, if we represent a call to setTimeout/setInterval with .
(例如,如果我们用setTimeout / setInterval表示调用.
) , a firing of the timeout/interval with *
and JavaScript code execution with [-----]
, the timelines look like: (,使用[-----]
执行带有*
和JavaScript代码执行的超时/间隔触发,时间轴如下所示:)
Timeout:
. * . * . * . * .
[--] [--] [--] [--]
Interval:
. * * * * * *
[--] [--] [--] [--] [--] [--]
The next complication is if an interval fires whilst JavaScript is already busy doing something (such as handling a previous interval). (下一个复杂情况是,如果在JavaScript已经忙于执行某些操作(例如处理上一个间隔)时会触发间隔。) In this case, the interval is remembered, and happens as soon as the previous handler finishes and returns control to the browser. (在这种情况下,会记住间隔,并在上一个处理程序完成后立即发生并将控制权返回给浏览器。) So for example for a doStuff() process that is sometimes short ([-]) and sometimes long ([-----]): (因此,例如doStuff()过程有时很短([ - ]),有时很长([-----]):)
. * * ? * ? * *
[-] [-----][-][-----][-][-] [-]
? represents an interval firing that couldn't execute its code straight away, and was made pending instead. (?表示无法立即执行其代码的间隔触发,而是取而代之。)
So intervals try to 'catch up' to get back on schedule. (因此,间隔试图“赶上”以按时恢复。) But, they don't queue one on top of each other: there can only ever be one execution pending per interval. (但是,它们并不排在一起:每个区间只能有一个执行挂起。) (If they all queued up, the browser would be left with an ever-expanding list of outstanding executions!) ((如果他们都排队等候,浏览器会留下不断扩展的未完成执行列表!))
. * ? ? x ? ? x
[------][------][------][------]
x represents an interval firing that couldn't execute or be made pending, so instead was discarded. (x表示无法执行或被挂起的间隔触发,因此被丢弃。)
If your doStuff() function habitually takes longer to execute than the interval that is set for it, the browser will eat 100% CPU trying to service it, and may become less responsive. (如果你的doStuff()函数通常需要比为它设置的时间间隔更长的时间来执行,那么浏览器会吃100%的CPU来尝试为它提供服务,并且可能会降低响应速度。)
Which do you use and why? (你用哪个?为什么?)
Chained-Timeout gives a guaranteed slot of free time to the browser; (Chained-Timeout为浏览器提供了保证的空闲时间;) Interval tries to ensure the function it is running executes as close as possible to its scheduled times, at the expense of browser UI availability. (Interval尝试确保其运行的功能尽可能接近其预定时间执行,但代价是浏览器UI可用性。)
I would consider an interval for one-off animations I wanted to be as smooth as possible, whilst chained timeouts are more polite for ongoing animations that would take place all the time whilst the page is loaded. (我会考虑一次性动画的间隔,我希望尽可能平滑,而链式超时对正在进行的动画更有礼貌,这些动画会在页面加载时一直发生。) For less demanding uses (such as a trivial updater firing every 30 seconds or something), you can safely use either. (对于要求较低的用途(例如每30秒触发一次微不足道的更新程序),您可以安全地使用它们。)
In terms of browser compatibility, setTimeout predates setInterval, but all browsers you will meet today support both. (在浏览器兼容性方面,setTimeout优先于setInterval,但您今天将遇到的所有浏览器都支持这两种浏览器。) The last straggler for many years was IE Mobile in WinMo <6.5, but hopefully that too is now behind us. (多年来最后一个落后者是WinMo <6.5的IE Mobile,但希望现在也落后于我们。)