問題
實現非同步循環時,你可能會遇到問題。
讓我們試著寫一個非同步方法,一次循環列印一次循環的索引值。
<script> for(var i = 0; i < 5; i++){ setTimeout(function(){ document.writeln(i);document.writeln("<br />"); },1000); } </script>
如上程式的輸出為:
5
5
5
5
5
原因
每次時間結束(timeout)都指向原始的i,而並非它的拷貝。所以,for迴圈使i成長到5,之後timeout運行並呼叫了當前i的值(也就是5)。
解決方法
有幾個不同的方式可以拷貝i。最普通且常用方法是透過宣告函數來建立一個閉包,並將i傳給此函數。我們這裡使用了自呼叫函數。
運行程式碼
<script> for(var i = 0; i < 5; i++){ (function(num){ setTimeout(function(){ document.writeln(num);document.writeln("<br />"); },1000); })(i); } </script>
輸出
0
1
2
3
4