2015-10-25 57 views
2
function a() { 
    for(i=0;i<4;i++){ 
     b(i); 
    } 
} 

function b(j){ 
    setTimeout(function(){ 
     console.log(j); 
    },3000); 
} 

a(); 

有人能请我解释一下上面的代码是如何在事件队列和执行上下文中执行的?事件队列函数回调

从我对JS的理解中,我知道直到JS文件中的所有代码都完成之后才会处理事件队列。所以首先在全局范围内调用a。然后在函数a()内部,存在调用b四次的for循环。所以我的问题是在函数b的每次调用中,一个计时器事件将被放置在事件队列中。此计时器事件是否等待三秒钟,然后回调传递给setTimeout方法的函数?或者它只是在队列中放置一个计时器事件,然后返回到函数a,再次调用b,这会在队列中放置另一个计时器事件。所以基本上,直到for循环未完成调用b四次,3秒钟的计时器事件将不会启动。但是当它调用b四次时,放在队列上的第一个定时器事件开始并回调到传入setTimeout参数的函数,并且由于它关闭,它知道j = 0。然后这发生在下一个队列中有3个事件?所以基本上,事件不会被处理,直到JS文件中的所有代码都完成了,在这种情况下,它是函数b的三次调用?

如果我的理解是完全错误的,请随时用自己的术语解释上面的代码,而无需阅读我的解释哈哈!

回答

3

此计时器事件是否等待三秒钟,然后回调传递给setTimeout方法的函数?或者它只是在队列中放置一个计时器事件,然后返回到函数a,再次调用b,这会在队列中放置另一个计时器事件。

后者。

撇开它不需要3秒钟拨打b 4次的事实,JavaScript将永远不会在函数中间暂停以运行另一个函数,因为事件已经触发。运行a()会太忙以查看是否有任何等待运行的超时事件。

+0

好的,只是为了澄清,四个事件将被放置在事件队列中。然后,一个事件将等待3秒钟并打印0,然后第二个事件将等待三秒钟并打印1,依此类推。但是当我运行代码时,它只等了三秒钟,然后打印出0,1,2,3。你能解释为什么它只等了三秒钟,实际上有四个事件放在队列中,每次超时三秒? – LP496

+1

因为它在你调用'setTimeout' 3秒后运行函数,而不是在你传递给'setTimeout'的最后一个函数运行3秒后运行。 – Quentin

+1

您的意思是:“3秒后记录j,3秒后记录j,3秒后记录j,3秒后记录j”,3秒后记录j,3 *秒后记录j, 3 *更多*秒,3 *更多*秒后记录j“。 – Quentin