这两个代码块关于 setTimeout 问题的区别

The differences between these two code blocks about setTimeout issue

我这里有两个代码块:

块 1:

setTimeout(function(){  
    func1();
    setTimeout(function(){ 
        func2(); 
    },500);
},500);

块 2:

setTimeout(function(){  
    func1();
},500);  
setTimeout(function(){  
    func2();
},1000);

这两个block有什么区别?(不仅是结果,还有执行过程)

在您的比较中,func2() 在第一个块中被调用的时间稍晚,然后在第二个块中被调用。为什么?因为它在触发新的 setTimeout() 计时器之前先执行 func1()

// First scenario:
setTimeout()
*---------*----------*===*
         500       1000
          Func1()
          *--*
             setTimeout()
             *-----------*
                        500
                         Func2()
                         *-*
// Second scenario:
setTimeout()
*---------*----------*
         500       1000
          Func1()    Func2()
          *-*        *-*

大多数情况下差异很小。但这取决于你在 func1() 中所做的事情。该函数的执行时间会将第二个超时推到相对于第一个 setTimeout().

更晚的时间点

关于执行、计时器和更多的东西,我去年在柏林的 jsConf 上看到了一个有趣的 in-depth session 关于 javascript 引擎如何在表面下工作,在关于调用堆栈、回调、异步请求等。花 25 分钟很好。

Philip Roberts: What the heck is the event loop anyway?

只有细微的差别。总的来说,您通常不会注意到任何差异。


在第一个代码块中,第二个计时器在 func1 有 运行 之后启动,因此计时将取决于 运行 需要多长时间。如果您像这样编写块 1,代码块的行为会更相似:

setTimeout(function(){  
    setTimeout(function(){ 
        func2(); 
    },500);
    func1();
},500);

不过,时间上还是会有细微的差别。如果浏览器正忙于 运行 在触发计时器时执行某些代码,则回调的执行将延迟到该代码完成。第一个计时器的任何延迟都会影响第二个计时器的启动时间。


另一个区别是你是否想停止计时器。对于块 1,第二个计时器依赖于第一个计时器,因此您不能单独停止它们。停止第一个计时器也会停止第二个计时器,而第二个计时器只能在第一个计时器完成后停止。

使用块 2,您可以随时独立停止任一计时器。 setTimeout 方法 returns 如果你想停止它使用的句柄:

var handle1 = setTimeout(function(){  
    func1();
},500);  
var handle2 = setTimeout(function(){  
    func2();
},1000);

稍后您可以使用 clearTimeout(handle1)clearTimeout(handle2) 来停止任一计时器。