2015-10-25 60 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