亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

JS關(guān)于for循環(huán)中使用setTimeout的四種解決方案

瀏覽:68日期:2024-03-28 14:29:37
概述

我們先來簡單了解一下setTimeout延時器的運行機制。setTimeout會先將回調(diào)函數(shù)放到等待隊列中,等待區(qū)域內(nèi)其他主程序執(zhí)行完畢后,按時間順序先進先出執(zhí)行回調(diào)函數(shù)。本質(zhì)上是作用域的問題。

因此若是這樣將不會得到想要的結(jié)果輸出1.2.3.4.5,而會連續(xù)輸出5個6。

for (var i=1; i<=5; i++) { setTimeout( function timer() {console.log( i ); }, i*1000 );}

這是因為setTimeout是異步執(zhí)行,每一次for循環(huán)的時候,setTimeout都執(zhí)行一次,但是里面的函數(shù)沒有被執(zhí)行,而是被放到了任務(wù)隊列里,等待執(zhí)行。只有主線上的任務(wù)執(zhí)行完,才會執(zhí)行任務(wù)隊列里的任務(wù)。也就是說它會等到for循環(huán)全部運行完畢后,才會執(zhí)行fun函數(shù),但是當for循環(huán)結(jié)束后此時i的值已經(jīng)變成了6,因此雖然定時器跑了5秒,控制臺上的內(nèi)容依然是6。

(注意:for循環(huán)從開始到結(jié)束的過程,需要維持幾微秒或幾毫秒,當定時器跑完一秒之后for循環(huán)早已經(jīng)做完了。)

我們來看另一種情況:

for (var i=1; i<=5; i++) { (function() {setTimeout( function timer() { console.log( i );}, i*1000 ); })();}

由setTimeout的運行機制可以知道,首先會運行外部的所有主程序,雖然for循環(huán)內(nèi)形成了閉包,但是fun并沒有發(fā)現(xiàn)一個實參所以跟第一個例子并無實際差別,仍然是連續(xù)輸出5個6。

解決方案1:閉包

使用閉包是很經(jīng)典的一種做法:

for (var i=1; i<=5; i++) { (function(j) {setTimeout( function timer() { console.log( j );}, j*1000 ); })(i);}

我們可以發(fā)現(xiàn)跟預(yù)期結(jié)果一致,依次輸出1到5,因是因為實際參數(shù)跟定時器內(nèi)部的i有強依賴。

通過閉包,將i的變量駐留在內(nèi)存中,當輸出j時,引用的是外部函數(shù)的變量值i,i的值是根據(jù)循環(huán)來的,執(zhí)行setTimeout時已經(jīng)確定了里面的的輸出了。

解決方案2:拆分結(jié)構(gòu)

我們還可以將setTimeout的定義和調(diào)用分別放到不同部分:

function timer(i) { setTimeout( console.log( i ), i*1000 );}for (var i=1; i<=5;i++) { timer(i);}

控制臺上輸出依然是依次輸出1到5。

解決方案3:let

這里再來說一說使用es6的let來解決此問題:

for (let i=1; i<=5; i++) { setTimeout( function timer() {console.log( i ); }, i*1000 );}

這個例子與第一個相比,只是把var更改成了let,可是控制臺的結(jié)果卻是依次輸出1到5。

因為for循環(huán)頭部的let不僅將i綁定到for循環(huán)中,事實上它將其重新綁定到循環(huán)體的每一次迭代中,確保上一次迭代結(jié)束的值重新被賦值。setTimeout里面的function()屬于一個新的域,通過var定義的變量是無法傳入到這個函數(shù)執(zhí)行域中的,通過使用let來聲明塊變量能作用于這個塊,所以function就能使用i這個變量了;這個匿名函數(shù)的參數(shù)作用域和for參數(shù)的作用域不一樣,是利用了這一點來完成的。這個匿名函數(shù)的作用域有點類似類的屬性,是可以被內(nèi)層方法使用的。

解決方案4:setTimeout第三個參數(shù)

for (let i=1; i<=5; i++) { setTimeout( function timer() {console.log( i ); }, i*1000, i );}

由于每次傳入的參數(shù)是從for循環(huán)里面取到的值,所以會依次輸出1到5。

以上就是JS關(guān)于for循環(huán)中使用setTimeout的四種解決方案的詳細內(nèi)容,更多關(guān)于JS使用setTimeout的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 高h猛烈做哭bl壮汉受小说 | 亚洲制服丝袜在线播放 | 国产五区 | 午夜老司机永久免费看片 | 亚洲美女毛片 | 欧美中文字幕一区二区三区 | 免费又爽又黄禁片观看1000 | 国产精品宾馆在线精品酒店 | 国产精品久久久久久福利69堂 | 日韩欧美亚洲一区精选 | vr欧美乱强伦xxxxx | 婷婷91| 异族中国vs黑人 | 轻轻啪在线视频播放 | 国内永久第一免费福利视频 | 小明精品国产一区二区三区 | 亚洲三页 | 九九热视频在线播放 | 一级做a爱免费观看视频 | 国产91区精品福利在线社区 | 伊人99综合| 91短视频社区在线观看 | 久久精品国产清自在天天线 | 亚洲精品精品 | 免费黄色大片在线观看 | 黄 色 片成 人免费观看 | 大伊香蕉精品视频在线天堂 | 韩国黄色毛片 | 亚洲一区二区欧美 | 泰国一级毛片aaa下面毛多 | 欧美做爱毛片 | 国产欧美精品系列在线播放 | 九月丁香婷婷 | 1000部国产成人免费视频 | 亚洲97i蜜桃网 | 一级一级一片在线观看 | a毛片视频| 欧美一级片黄色 | 色噜噜五月综合激情久久爱 | 日本一本在线视频 | 日本特黄特色高清免费视频 |