Проблема с порядком добавления в файловом ридере

У меня есть функция JQuery, которая читает FilesList и отображает изображение в html-объекте IMG.

function load_images(files) {
    for (var i = 0; i < files.length; i++) {
        // Validate the image type
        if(validate_file(files[i])) {
            var reader = new FileReader();
            reader.onload = function(e) {    
                $(".upload_thumbnails").append(render_thumb(e.target.result, i)); // Return a string with the img object
            };
        } 
        reader.readAsDataURL(f);
    } 
}

Но мои изображения не добавляются в последовательном порядке списка файлов. Список файлов (файлы var) реализуется с помощью объекта html с несколькими входными файлами.

Есть ли у вас какие-либо идеи ?


person Ludovic    schedule 04.11.2013    source источник
comment
Это асинхронное чтение, поэтому   -  person Johan    schedule 05.11.2013


Ответы (1)


Метод readAsDataURL является асинхронным, что означает, что ваш цикл будет создавать множество запросов для загрузки данных, но поскольку метод асинхронен, невозможно узнать, в каком порядке будет вызываться обратный вызов onload. Поведение недетерминированное.

Это можно решить, сохранив все элементы в массиве вместе с их индексами, а затем фактически отрендерив все изображения, когда все они будут полностью загружены.

Другой альтернативой является создание div-заполнителя при запуске запросов и захват его при закрытии обратного вызова onload. Затем вы можете добавить изображение в этот div, это приведет к желаемому поведению.

Нравится:

function load_images(files) {
    for (var i = 0; i < files.length; i++) {
        // Validate the image type
        if(validate_file(files[i])) {
            var reader = new FileReader(),
                div    = $("<div></div>");
            $(".upload_thumbnails").append(div);            

            reader.onload = function(e) {    
                div.append(render_thumb(e.target.result, i)); // Return a string with the img object
            };
        } 
        reader.readAsDataURL(f);
    } 
}
person Hugo Tunius    schedule 04.11.2013
comment
Я понимаю свою ошибку, но с твоим решением проблема такая же нет? Он просто создаст много пустых div и последний div со всем изображением в нем. - person Ludovic; 05.11.2013
comment
Действительно? Я не понимаю, как это могло случиться, все должно работать так, как вы хотели. Не могли бы вы опубликовать jsFiddle? - person Hugo Tunius; 05.11.2013
comment
Значит, теперь все работает так, как задумано? Если да, отметьте вопросы как отвеченные. - person Hugo Tunius; 10.11.2013
comment
Нет, посмотрите HTML-код при загрузке изображений, у вас есть 3 пустых div, а затем div со всеми изображениями в нем. Заказ неправильный. - person Ludovic; 10.11.2013
comment
О да, конечно. Переменная поднимается. Вам нужно будет создать область действия с функцией. Вот так, jsfiddle.net/u3d99/3 Это не совсем оптимально, но работает . Например, вы можете использовать массив forEach вместо цикла for. Так было бы лучше. - person Hugo Tunius; 10.11.2013
comment
Отлично, спасибо вам большое! Я изменю свой for на forEach. - person Ludovic; 10.11.2013