对How JavaScript Timers Work的理解
John Resig在How JavaScript Timers Work一文中,对setTimeout和setInterval的分析很精辟:
总结如下:
- JavaScript engines only have a single thread, forcing asynchronous events to queue waiting for execution.
- setTimeout and setInterval are fundamentally different in how they execute asynchronous code.
- If a timer is blocked from immediately executing it will be delayed until the next possible point of execution (which will be longer than the desired delay).
- Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).
我的心得:
- 无论是setTimeout还是setInterval,触发时,如果当前进程不为空,都得去排队等待执行,这一点上是无差异的。
- 区别是,setTimeout只需排一次队,setInterval则需要按照预设的间隔时间,每到时间点都去排一下。
- setInterval去排队时,如果发现自己还在队列中未执行,则会被drop掉。也就是说,同一个inerval,在队列里只会有一个。
- 因为队列机制,无论是setTimeout还是setInterval,第一次触发时的时间,只会等于大于预设时间,不可能小于。
- 对于setInterval来说,如果执行时间大于预设间隔时间,很可能导致连续执行,中间没有时间间隔,这是很糟糕的,很可能会耗费大量cpu.
因此,对于动画来说,如果单帧的执行时间大于间隔时间,用setTimeout比用setInterval更保险。John Resig在回复中也表明了这个观点:
It really depends on the situation – and how the timers are actually being used. setInterval will, most likely, get you more ‘frames’ in the animation but will certainly tax your processor more. A lot of frameworks end up using setTimeout since it degrades more gracefully on slower computers.
一个简单的测试页面:timer_test.html(请在Chrome下运行,注意那些零值或接近零的值,setInterval没有interval了!)
因此,在这种情况下,采用setTimeout更保险:
setTimeout(function(){
/* Some long block of code... */
setTimeout(arguments.callee, 10);
}, 10);
当然,大部分情况下,单帧执行时间都小于预设的间隔时间,上面分析的差异,是感觉不大出来的。


March 9th, 2009 on 17:49
其实我想说
测试页面 404 了
April 27th, 2009 on 21:35
测试页面,啥意思?
September 13th, 2009 on 16:28
巧了,射雕大侠,俺在自己博客里翻译过这篇文章,收获蛮大的。
指出一点,setTimeout相比setInterval是更加保险(许多图书上也提了),但是如果想停止动画,setTimeout就比较麻烦。而setInterval则非常简单,因此很多流行框架里使用的就是setInterval而没有使用setTimeout。
leave a reply