js的for循環中出現異步函數,回調引用的循環值老是最後一步的值?

這幾天跟着視頻學習node.js,碰到不少的異步函數的問題,如今將for循環中出現的異步函數回調值的問題總結以下:javascript

具體問題是關於遍歷文件夾中的子文件夾的,for循環包裹異步函數的代碼:前端

for (var i = 0; i < files.length; i++) {
    var itemFile = files[i];
    fs.stat("./uploads/" + itemFile, function (err, stats) {    
        if (stats.isDirectory()) {
            console.log(itemFile+i);    
        } else {
            console.log(2);
        }
    });
}

輸出結果是:java

wedding3
wedding3
wedding3

for循環是同步任務,i在不斷滴增長直到等於file.length時候,循環再也不執行,即等於3(本身實驗代碼)。而循環內部的判斷是不是文件夾的isDirectory函數是異步函數,也就是說內部的console.log(itemFile+i); 的執行任務被排在了任務隊列的最後,因此for循環自己會先執行3次,可是不執行回調裏面的任務,for循環都結束時,回調函數裏面的console.log纔開始執行第一次,因此每次輸出都是wedding3.node

固然這並非咱們想要的結果,解決方法能夠經過自執行函數傳參(匿名函數),這樣就造成了不受外界變量影響的局部做用域。如:jquery

for (var i = 0; i < files.length; i++) {
    (function(i){
        var itemFile = files[i];
        fs.stat("./uploads/" + itemFile, function (err, stats) {    
            if (stats.isDirectory()) {
                console.log(itemFile+i);    
            } else {
                console.log(2);
            }
        });
    })(i);  
}

輸出獲得:異步

cat0
dog1
wedding2

這樣就能夠解決以前只輸出最後循環的值的問題。函數

前端頁面開發也會碰到相似的問題,好比setTimeout異步執行的問題,在前端能夠經過jquery的each方案解決。用jQuery的 $.each(),自帶回調函數,造成了函數做用域.學習

<script type="text/javascript">
    var arr = ["dog",cat","wedding"];
    $.each(arr, function(key, value) {
        setTimeout(function() {
            console.log(key);
            console.log(value);
        }, 2000);
    });
</script>
相關文章
相關標籤/搜索