Будет ли событие, для завершения которого требуется много времени, изменить значение "изменяемой переменной"

У меня большой for цикл (где-то около 1000 итераций), в котором загружается URL-адрес изображения из объекта и, если он загружается правильно, объект добавляется в массив. Мой вопрос: из-за асинхронной природы Javascript, если загрузка изображения занимает много времени, for Цикл продолжит итерацию, и, таким образом, изменит значение индекса и тем самым загрузит не тот элемент в массив. Я получаю предупреждение от моего редактора, что Mutable variable is accessible from closure в следующем коде:

function createArray(data){
    var entries = data['entries'];
    for (var k = 0, j = entries.length; k < j; k++) {
            if (entries[k].type = 'image') {
                var img = new Image();
                img.onload = function(){
                    validArray.push(entries[k]); //Here is where it is added to array. This [k] is the mutable value - wondering if the image takes a long time to load, if [k] will be incremented 
                };
                img.onerror = function(){
                    console.log('error: bad image source');
                };
                img.src = entries[k].url;
            } else {
                console.log('Not an image');
            }
        }
    }

1 ответ

Решение

Ответ - да, переменная k вероятно, изменится ко времени выполнения обратного вызова. Хотя есть простое решение - обернуть функцию в замыкание. Таким образом, вы можете создать локальную копию kили, что более осмысленно, локальная копия записей [k]:

img.onload = (function(entry) {
    return function(){
        validArray.push(entry); 
    };
})(entries[k]);

Или, если вы предпочитаете упростить синтаксис, вы можете написать вспомогательную функцию, такую ​​как "getAddFunction":

var getAddFunction = function(entry) {
    return function() {
        validArray.push(entry); 
    };
};

А потом просто:

img.onload = getAddFunction(entries[k])
Другие вопросы по тегам