2016-11-17 79 views
2

爲什麼Javascript顯示setTimeout函數同步和異步輸出?

for(var i = 2;i >= 1;i--) { 
 
    setTimeout(function (i) { 
 
    console.log(i); 
 
    },1000); 
 
    console.log("hii"); 
 
}

此代碼給我輸出

  • HII

  • HII

  • 不確定

  • 不確定

凡如下格式使用的setTimeout後給出不同的輸出

for(var i = 2;i >= 1;i--) { 
 
    setTimeout(print(i),5000); 
 
    console.log("hii"); 
 
} 
 
function print(i) { 
 
    console.log(i); 
 
}

此代碼給我輸出

  • HII

  • HII

我不明白,爲什麼在第二種情況下的代碼同步執行。

+1

您正在執行'印刷(一)'因爲你是循環的回報值。它不返回一個函數(回調)。你需要運行'setTimout(函數名或者匿名函數)'而不是'setTimeout(somefunction())' – mplungjan

回答

5

因爲您已經調用了print函數,所以它不會作爲回調函數傳遞。在這種情況下,它將完成print函數的執行,然後將返回值作爲第一個參數傳遞給setTimeout。

這是你正在嘗試: -

for(var i = 2;i >= 1;i--) { 
    setTimeout(print(i),5000); 
    console.log("hii"); 
} 
function print(i) { 
    return function(){console.log(i)} 
} 
2

在第一個例子,你傳遞一個函數,它接受一個參數,i到setTimeout的,但setTimeout的不傳遞任何參數給這個函數(或任何功能),當它調用它。因此i在該函數中未定義,因此輸出undefined

在第二個示例中,您正在調用print並將結果傳遞給setTimeout。但是print會立即執行,所以這就是爲什麼在每次迭代之前輸出一個數字的原因。

1

for(var i = 2;i >= 1;i--) { 
 
    setTimeout(function (i) { 
 
    console.log(i); 
 
    },1000); 
 
    console.log("hii"); 
 
}

的Javascript具有函數級範圍,並且不塊級範圍。所以,當你調用內部的setTimeout for循環象下面這樣:

setTimeout(function (i) { 
     console.log(i); 
     },1000); 

發生的事情是一個局部變量i引入尚未設置爲任意值,因此它在JS返回undefined。在你的第二個片段

回調被執行,並顯示在屏幕上