for循環 嵌套延時器 實例及解決方案


 for循環 嵌套延時器 實例及解決方案

首先         看一個經典的for循環嵌套延時器的案例

for(var i = 0;i<lg;i++){// lg = 6
        setTimeout(function(){ console.log(i); //此時輸出為 6 個 6
        },1000) }

我們想要的結果是在for循環中一次打印出 的 值。即0,1,2,3,4,5;但是輸出6個相同的個數字是什么原因呢?

這主傳進去要是因為setTimeout的執行時異步執行的,而for循環的執行卻非常的快,所以,在1s后執行定時器函數時, i  已經 循環到了最大值6,其他的i值已經被銷毀,此時再執行定時器,則是把 i=6傳進去了,所以造成了這樣的結果。

那我們應該怎么解決這個問題呢?

解決這個問題首先是要解決 值的變量銷毀問題,即瀏覽器的垃圾回收機制:

第一種方法:將延時器中的函數用一個自執行函數包起來,把每個循環中的 i 在被回收之前直接傳入到自執行函數中,這樣就可以避免被回收:如下:

for (var i = 0; i < lg; i++) {//lg = 6
            setTimeout((function(a) { console.log(a);//操縱變量a,和i無關 此時輸出為0,1,2,3,4,5
            })(i), 1000);//將 i 作為變量傳入
}

但是這樣寫會出現一個問題,函數直接打印了,並沒有一秒的延遲,原因是將自執行函數放在定時器中,會直接執行,並不是1秒后再執行,所以在這種方法上做了一些改進,即第二種方法:

第二種方法:將延時器整個的包裹在一個子執行函數中,這樣就相當於同時定義了6個延時1s的延時器:

for (var i = 0; i < lg; i++) {//lg = 6
        (function(a){//自執行函數,獲取i
            setTimeout(function() { console.log(a);//操縱變量a,和i無關 此時輸出為 0,1,2,3,4,5 且在1s延遲后輸出
            }, 1000) })(i) }

這樣就完美的解決問題了;如果你想要每隔一秒輸出一個值,而不是同時輸出,則可以將參數傳進時間中:

 for (var i = 0; i < lg; i++) {//lg = 6
        (function(a){//自執行函數,獲取i
            setTimeout(function() { console.log(a);//操縱變量a,和i無關 此時輸出為 0,1,2,3,4,5 且在1s延遲后輸出
            }, a*1000)//將 i 的值傳進來 ,這樣就可以每個一秒輸出一個值
 })(i) }

 

setInterval定時器和setTimeout 不同,因為是執行次數的原因,不能將 i  的值傳進時間中,會造成多次重復;

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM