MyFunction()vs window.setTimeout('MyFunction()',0)?

时间:2009-09-01 02:15:21

标签: javascript

在javascript中,这两者之间有什么不同:

// call MyFunction normal way 

MyFunction();

// call MyFunction with setTimeout to 0 //

window.setTimeout('MyFunction()', 0);

我问的原因是因为最近遇到的情况是代码只有在我使用setTimeout(0)来调用函数时才有效。 根据我的理解,setTimeout(0)与直接调用函数完全相同,因为您没有设置任何延迟。但是从我看到它在代码中的工作原理来看,setTimeout(0)似乎最后被执行了。

是否有人能够确切地澄清setTimeout(0)如何按照其他函数调用的顺序进行调用?

3 个答案:

答案 0 :(得分:17)

setTimeout()总是导致JavaScript块被排队等待执行。这是一个何时执行的问题,由延迟决定。 以延迟0调用setTimeout()将导致JavaScript解释器意识到它当前正忙(执行当前函数),并且解释器将调度脚本块在当前调用堆栈为空时执行(除非那里)是排队的其他脚本块。)

调用堆栈可能需要很长时间才能变空,这就是您看到执行延迟的原因。这主要是由于单个窗口上下文中JavaScript的单线程特性。

为了完整起见,MyFunction()将立即执行该函数。不会有排队。

PS John Resig has some useful notes on how the JavaScript timing mechanism works

PPS :只有在使用setTimeout(fn(),0)时代码“似乎工作”的原因是因为浏览器只有在当前调用堆栈完成时才能更新DOM 。因此,下一个JavaScript块将识别DOM更改,这在您的情况下是非常可能的。 setTimeout()回调总是会创建一个新的调用堆栈。

答案 1 :(得分:3)

我猜测超时仅在页面完全加载时开始,而只是一个简单的'MyFunction()'将在处理后立即执行。

答案 2 :(得分:0)

当前线程完成后,计时器将尝试执行。这取决于您调用window.setTimeout()的位置。如果它在javascript标记中,但不在函数内部,那么一旦到达javascript标记的末尾就会调用它。例如:

<html>
<script type="text/javascript">
setTimeout(function(){alert("hello")},0);
var d=Number(new Date())+1000;
while(Number(new Date())<d){

}
alert("hi");
</script>
</html>

如果在事件发生的函数内调用setTimeout,例如onload,那么它将等到事件处理函数返回:

<html>
<script type="text/javascript">
document.addEventListener("mousedown",function(){
    setTimeout(function(){alert("hello")},0);
    var d=Number(new Date())+1000;
    while(Number(new Date())<d){

    }
    alert("hi");
}, true);
</script>
</html>

当另一个线程正在运行时,不可能在JavaScript中使一个线程等待。事件侦听器将在它们开始运行之前等待当前线程完成。

唯一的例外是Web Workers,但是它们运行在不同的文件中,并且它们之间进行通信的唯一方法是使用事件侦听器,因此当您可以在另一个工作时发送消息时,它将不会接收到消息,直到完成,或手动检查消息。