誰能給我解釋一下下面的代碼和JavaScript的行爲流動
for(var i = 0; i < 5; i++)
{
setTimeout(function(){
document.write('Iteration ' + i + ' <br>');
},1000);
}
document.write('DONE!');
爲什麼它打印「DONE!」第一? 不應該打印循環的所有值,然後打印'完成!'?
誰能給我解釋一下下面的代碼和JavaScript的行爲流動
for(var i = 0; i < 5; i++)
{
setTimeout(function(){
document.write('Iteration ' + i + ' <br>');
},1000);
}
document.write('DONE!');
爲什麼它打印「DONE!」第一? 不應該打印循環的所有值,然後打印'完成!'?
它爲什麼打印'完成!'第一?它不應該打印循環的所有值,然後打印'完成!'?
不,你明確地告訴它不要;相反,您剛剛創建了五個函數,並且五次調用setTimeout
以使它們能夠在瀏覽器中稍後調用。
此代碼:
setTimeout(function(){
document.write('Iteration ' + i + ' <br>');
},1000);
調用函數setTimeout
,傳遞你看到的功能。那個功能是當時調用的而不是。它剛剛創建。 setTimeout
將其稱爲後,因爲它的工作。 (並且當它,它會吹走文件,因爲頁面的主解析後調用document.write
完成隱含確實document.open
,它消滅了之前的文件。)
因此,這裏是與該代碼會發生什麼:
i
已創建。0
。setTimeout
與傳入的函數對象的引用一起被調用,以及值1000
。i
遞增。1
,2
,3
和4
的i
的值。document.write
被調用值'DONE!'
document.write
,隱含地做一個document.open
,它吹走了現有的文檔並用Iteration 5 <br>
(是的,真的是5)代替它。的原因,我們看到Iteration 5
五次,而不是Iteration 0
,然後Iteration 1
等,是這些功能有一個持久的參考變量i
,而不是它的價值時,他們創建的,所以他們都稍後再閱讀它的價值,就像它們跑步的時候一樣。
請參考此線程並檢查答案2:http://stackoverflow.com/questions/16523870/is-javascript-synchronousblocking-or-asynchronousnonblocking-by-default – ProblemSolver
@ProblemSolver:不知道你想說什麼,但請注意,並非所有人都能以相同的順序看到答案。如果您想引用特定的答案,請使用它下面的「分享」鏈接來獲取指向該特定答案的鏈接。但是我沒有看到上面沒有涉及的任何內容。 –
正常情況下的Javascript是Synchronous
逐行執行,但通過代碼更改,您可以在某個時間作爲異步,但實際上並不會在單獨的線程上執行。
好吧,如果你要打印Done
的文件撰寫完成後立即
length = 0;
for(var i = 0; i < 5; i++)
{
setTimeout(function(index){
console.log('Iteration ' + index + ' <br>');
length++;
callback();
}(i),1000);
}
function callback(){
if(length == 5)
console.log('DONE!');
}
我們在這裏做什麼是我們增加計數器,並嘗試以後每次調用回調函數的遞增,當計數器達到5意味着所有5個功能被稱爲,然後我們能夠打印Done
。
作爲一個側面和重要的提示,你試圖打印0,1,2,3,4,但實際上當你運行你的代碼時,它會給你5,5,5,5,因爲你寫i
和i
在打印達到5的時候,這就是爲什麼它會離開for循環,但是您注意到我添加的代碼,我將i
作爲參數傳遞給該函數,以便它可以爲我們保存值並且當的時間來執行funtion將會寫入0,1,2,3,4
'DONE!在for循環完成後正在打印。 – Rayon
[WindowTimers.setTimeout()](https://developer.mozilla.org/zh-CN/docs/Web/API/WindowTimers/setTimeout) – Liam
流程爲你先設置了5個超時函數,然後打印完成 - 按順序完成。這些函數在間隔後執行,這就是爲什麼先打印完成,但程序的流程是第一個操作是設置5個超時回調。 – Mjh