关于计时器

一. 三个知识点

1. 计时器并不是JS语言的一部分,而是浏览器引入的方法和对象的一部分;

2. 在OS上,浏览器的最小延时时间为10ms,在windows上为15ms(注: 据我的测试, 15ms仅针对IE, 其他浏览器可以设置低于15ms的延时, 而不会被忽略);

3. 浏览器可以提供非常小的延迟时间,但其精确度得不到保证(即浏览器不能保证你所指定的精确的时间间歇), 这与浏览器如何处理JS的垃圾回收有关;

二. IE中设置延时的一个例外

IE为setInterval提供的延时时间不能为0, 当setInterval的延时时间为0时,它会转变成setTimeout(仅执行一次回调函数).

解决方法: 可以通过为其提供1ms的延迟来解决这个问题, 由于所有浏览器都能自动向上舍入任何低于最小延时时间的值,所以1ms与0ms是一样的(注: 我认为仅针对IE, 因为15ms的最小延时仅针对IE).

三. setTimeout与setInterval的区别

1. 例子一

setTimeout(func, 15);与setInterval(func, 15);

a. setTimeout在延迟15秒后, 执行func, 仅执行一次;

b. setInterval每隔15秒执行一次func, 会执行多次.

2. 例子二

setTimeout(function() {
    function callback() {/* other code */}
    setTimeout(arguments.callee, 15);
}, 15);
setInterval(function() {
    function callback() {/* other code */}
}, 15);

a. setTimeout在callback执行完之后, 才会开始下一个延时, 在两次callback执行之间, 至少有15ms的延时(下图解释为什么至少有15ms):
为什么两次callback执行之间, 至少有15ms的延时?

b. setInterval则是每隔15ms, 就尝试执行一次callback, 它不管当前的时间段内是否有其他函数正在执行, 由于单线程的缘故, 这就导致了每隔15ms, 就会有一个callback去排队(这可能会出现一种情况: 在某个时间段内, 一大群callback被毫无延迟的执行, 如下图所示):
某个时间段内,  大量callback被无延迟的执行
从上图可以看到: 每隔15ms, 便会有一个delay callback去排队, 而当click callback执行完毕之后, 第2, 3次产生的delay callback会毫无延迟的执行(不考虑垃圾回收的时间, 中间没有间歇).

, , ,

Comments

boin at 2009年12月12日 2:42 下午

nice post!

Leave a comment!