簡體   English   中英

為什么onload處理程序無法正確填充我的數組?

[英]Why does the onload handler fail to properly populate my array?

我需要一個包含blob的數組,所以我的代碼是:

for (var i = 0; i < total; i++) {

    var xhr = createXHR();

    xhr.open('GET', 'img/tiles/' + zeroFill(i, 4) + '.png', true);
    xhr.responseType = 'blob';

    xhr.onload = function() {

        arr[i] = new Blob([this.response], {type: 'image/png'});
        // console.log(arr[i]);

    };

    xhr.send();

}

當我輸出arri位置時,控制台會正確顯示blob(至少說出它的大小)。 如果我嘗試顯示以前的位置,則會得到undefined

如果在所有XHR請求都完成后再看一下arr ,控制台將顯示一個奇怪的數組,其中每個位置均未定義 ,而最后一個位置中包含未完成的blob。

這是一個非常常見的錯誤。 for循環完成后, onload處理程序將被調用為long。 這意味着i的值將是循環結尾處的值,而不是您希望它位於for循環中間的值。

要解決此問題,您需要以某種形式在閉包中捕獲i的正確值。 有很多方法可以做到這一點。

這是一種使用自執行函數的方法,該函數在函數參數中捕獲i的值。 i的值傳遞給自執行函數,該函數為for循環的每次迭代創建一個新范圍,然后在該范圍的函數參數中捕獲i的正確值。 該函數參數在每次調用自執行函數時都唯一存在,因此將保留所需的值,直到將來某個時候onload處理程序時才需要該值。 外觀如下:

for (var i = 0; i < total; i++) {

    var xhr = createXHR();

    xhr.open('GET', 'img/tiles/' + zeroFill(i, 4) + '.png', true);
    xhr.responseType = 'blob';

    (function(index) {
        xhr.onload = function() {

            arr[index] = new Blob([this.response], {type: 'image/png'});
            // console.log(arr[index]);
       }

    })(i);

    xhr.send();

}

您所有的ajax回調都引用外部作用域的相同i 這意味着當您的ajax調用完成時,它們都會將數據推送到相同的i ,該total-1total-1

附帶說明:以前的索引填充為null只是將數據推入較大索引時JS數組的工作方式。

常見的解決方案是使用閉包,將當前i值捕獲到新的執行上下文中:

//read comments in the numeric order
xhr.onload = (function(i) {//2. the `i` inside the function now references
                           //a new `i` independent from the outer `i`
    return function(){//3. returns a function handler that executes on xhr.onload
        arr[i] = new Blob([this.response], {type: 'image/png'});
        console.log(i); //4. logs the IIFE execution context's `i`,
                        //as it is the closest (inner-most scope chain-wise) `i`
    };
}(i)); //1. Passes outer current `i` as argument to this
       //Immediately-Invoked Function Expression (IIFE)

可以在此處找到上述代碼的詳細說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM