关于setTimeout问题的这两个代码块之间的差异

时间:2015-03-18 08:28:07

标签: javascript settimeout

我这里有两个代码块:

block1:

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

block2:

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

这两个块之间有什么区别?(不仅是结果,还有执行程序)

2 个答案:

答案 0 :(得分:2)

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

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

大多数情况下的差异很小。但这取决于你在func1()中做了什么。该函数的执行时间将第二次超时推送到相对于第一个setTimeout()的稍后时间点。


关于执行,计时器等等,我去年在柏林的jsConf上看到了一个有趣的深入会议,关于javascript引擎如何在表面之下工作,关于callstack,回调,异步请求等。那些花了25分钟。

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

答案 1 :(得分:1)

只有微妙的差异。总的来说,你通常不会发现任何差异。


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

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

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


另一个区别是你想要停止计时器。使用块1,第二个计时器取决于第一个计时器,因此您无法单独停止它们。停止第一个计时器也将停止第二个计时器,第二个计时器只能在第一个计时器完成后停止。

使用块2,您可以随时单独停止任一计时器。 setTimeout方法返回一个句柄,如果要停止它,则使用该句柄:

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

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