關(guān)于JS的for循環(huán)包裹異步函數(shù)的問題

今天一個做后端的同事問了我一個JS的問題:

有個循環(huán),循環(huán)一個異步回調(diào),為啥回調(diào)引用的循環(huán)值都是最后一步循環(huán)的循環(huán)值?然后,又有些時候無論什么循環(huán)值都得不到?

好吧,JavaScript跟PHP的循環(huán)有時候確實不一樣,JavaScript的函數(shù)有同步函數(shù)跟異步函數(shù)的區(qū)分,PHP里面沒這種概念,拿PHP的常識來理解JavaScript有時候行不通。關(guān)于JS異步機制的研究,看我另一篇JS異步執(zhí)行機制理解。

我想了想,他說的“什么循環(huán)值也得不到的”,應(yīng)該是下面這個情況:

<script type="text/javascript">
var arr = [1,3,5,7,9];
var arrLength = arr.length;

for (var i = 0; i < arrLength; i++) {
    setTimeout(function() {
        console.log(i);
        console.log(arr[i]);
    }, 2000);
}
</script>

結(jié)果是:

5
undefined
5
undefined
5
undefined
5
undefined
5
undefined

for循環(huán)有一個特點,就是“i判斷失敗一次才停止”。所以,i在不斷的自加1的時候,直到i等于5,i才失敗,這時候循環(huán)體不再執(zhí)行,會跳出,所以i等于5沒錯。那么為什么5次循環(huán)的i都等于5?原因就是setTimeout()的回調(diào),也就是console.log(i);console.log(arr[i]);被壓到任務(wù)隊列的最后,for循環(huán)是同步任務(wù),所以先執(zhí)行,等于是空跑了5次循環(huán)。于是,i都等于5之后,console.log(i);console.log(arr[i]);剛開始第一次執(zhí)行,當(dāng)然輸出全是5。

然后,同事說,有時候JS的for循環(huán),永遠只得到最后一個循環(huán)值,那其實他用的是for...in...循環(huán)。具體不多解釋了。

我既然聽了他的問題,就要給他解決方案。

我先建議他用自執(zhí)行函數(shù)傳參,這樣自執(zhí)行函數(shù)內(nèi)部形成了局部作用域,不受外部變量變化的影響。范例代碼是:

<script type="text/javascript">
var arr = [1,3,5,7,9];
var arrLength = arr.length;

for (var i = 0; i < arrLength; i++) {
    (function(i) {
        setTimeout(function() {
            console.log('i是' + i);
            console.log('value是' + arr[i]);
        }, 2000);
    })(i);
}
</script>

得到:

Paste_Image.png

不但解決了undefined的問題,而且解決了異步函數(shù)傳參的問題。

然后我把范例代碼給了他。然而,他的JS代碼寫的太亂,拿這個例子改居然改不對。于是我又給了一個jQuery方案給他:

<script type="text/javascript">
var arr = [1,3,5,7,9];

$.each(arr, function(key, value) {
    setTimeout(function() {
        console.log('i是' + key);
        console.log('value是' + value);
    }, 2000);
});
</script>

用jQuery的$.each(),自帶回調(diào)函數(shù),形成了函數(shù)作用域,這娃最終解決了問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 8,140評論 2 17
  • 弄懂js異步 講異步之前,我們必須掌握一個基礎(chǔ)知識-event-loop。 我們知道JavaScript的一大特點...
    DCbryant閱讀 2,889評論 0 5
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,245評論 0 1
  • Node.js是目前非常火熱的技術(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計出JavaScri...
    w_zhuan閱讀 3,737評論 2 41
  • 單例模式 適用場景:可能會在場景中使用到對象,但只有一個實例,加載時并不主動創(chuàng)建,需要時才創(chuàng)建 最常見的單例模式,...
    Obeing閱讀 2,321評論 1 10

友情鏈接更多精彩內(nèi)容