setTimeout与setInterval再次比较

3

我知道setTimeoutsetInterval之间有区别,但请看这两个代码示例:

function myFunction(){
   setTimeout('myFunction();', 100);
   doSomething();
}
setTimeout('myFunction();', 100);

并且

function myFunction(){
   doSomething();
}
setInterval('myFunction();', 100);

请注意,在第一个示例中,我在函数开头调用setTimeout,然后调用doSomething。因此,从doSomething()没有额外的延迟。这是否意味着这两个示例完全相同?或者还有更微妙的区别吗?
2个回答

11
它们在功能上基本相同,但是有一些区别。其中一个区别在于浏览器处理如果doSomething的执行时间超过了间隔时间。使用setInterval时,至少一些浏览器将跳过下一个间隔,如果doSomething仍在运行。因此,如果像你使用100毫秒,并且doSomething需要110毫秒才能运行,则下一次运行将推迟90毫秒(当然,所有这些时间都是近似值)。
另一个区别是使用setTimeout时,您每次都会获得一个新的句柄,而使用setInterval则只获得一个句柄。
另一个与您的示例不同之处在于,在setTimeout示例中,您每次都要启动JavaScript解析器/编译器,而使用setInterval时,您只需启动一次解析器/编译器。但是,这种区别并不重要,因为您根本不应该这样做--请参见下文。
但是,忽略细微差别,您所拥有的功能是相同的。
侧记:将字符串传递给setTimeoutsetInterval不是最佳实践。相反,请传递函数引用。
// setTimeout
function myFunction(){
   setTimeout(myFunction, 100);
   doSomething();
}
setTimeout(myFunction, 100);

// setInterval
function myFunction(){
   doSomething();
}
setInterval(myFunction, 100);

传入一个字符串会启动JavaScript解析器,与eval的作用相同。尽可能避免使用它(几乎总是可以避免)。


1
谢谢你的回答。当然使用函数引用更好。但这给了我一个想法。如果你使用字符串运行 setTimeout,那么就可以将变量传递给函数,例如 setTimeout('myFunction('+i+');', 100);。每次调用 myFunction 时都可以评估这个变量(本地)。我没有看到使用 setInterval 做同样的事情的方法,除了全局变量(不传递给 myFunction)。所以这里还有另一个区别。 - freakish
@freakish:没错。我不会那样做,但如果你使用字符串,你是对的,这是它们之间的另一个区别。 - T.J. Crowder
+1 很好的回答,详细且写得很好,很高兴你没有永远离开 TJ :) - alex
1
@alex:谢谢,你太好了。我现在只能贡献以前水平的10%左右,我对Atwood的社区管理愿景不能认同。 - T.J. Crowder

1
T.J.克劳德(T.J. Crowder)解释了主要的区别,还可能出现另一个更微妙的差别(我改变了时间尺度,因为这样更容易解释):
让我们使用非常大的超时时间:1天来绘制差异。你在第1天的00:00调用了这两个方法,并让它运行1年...
一年后,由setInterval调用的方法将在00:00 +一些毫秒执行(因为您可能不是唯一一个要求处理器在此时刻做事情,而且操作系统计时器无论如何都具有粒度)。
但是,您的setTimeout方法将稍后发生,可能在00:01左右,因为每天它都会在请求时间之后一点点被调用,并要求下一天在相同时间调用...
PS:在某些情况下,它也可能在请求时间之前被调用,但通常情况下会在之后运行:-D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接