for循环 嵌套延时器 实例及解决方案
生活随笔
收集整理的這篇文章主要介紹了
for循环 嵌套延时器 实例及解决方案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
for循環 嵌套延時器 實例及解決方案
首先 看一個經典的for循環嵌套延時器的案例
for(var i = 0;i<lg;i++){// lg = 6
setTimeout(function(){
console.log(i); //此時輸出為 6 個 6
},1000)
}
我們想要的結果是在for循環中一次打印出i的 值。即0,1,2,3,4,5;但是輸出6個相同的個數字是什么原因呢?
這主傳進去要是因為setTimeout的執行時異步執行的,而for循環的執行卻非常的快,所以,在1s后執行定時器函數時, i 已經 循環到了最大值6,其他的i值已經被銷毀,此時再執行定時器,則是把 i=6傳進去了,所以造成了這樣的結果。
那我們應該怎么解決這個問題呢?
解決這個問題首先是要解決i值的變量銷毀問題,即瀏覽器的垃圾回收機制:
第一種方法:將延時器中的函數用一個自執行函數包起來,把每個循環中的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 的值傳進時間中,會造成多次重復;
總結
以上是生活随笔為你收集整理的for循环 嵌套延时器 实例及解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ysql怎么处理百分数? “%”
- 下一篇: 映射是什么?函数是什么?映射与函数的关系