Отправка запросов на изображения синхронно с jquery

У меня есть страница, где я получаю канал с YouTube, а затем отображать это на этой странице. Есть 3 строки каждого из 4 изображений, каждое из которых соответствует видео на YouTube. Я получаю эти ссылки на изображения с самого канала YouTube.

Чего я хочу достичь, так это рендеринга этих изображений, я хочу получить изображение с YouTube по одной строке за раз. Если загрузка изображений не завершена, я хотел бы подождать, пока будут получены изображения следующей строки.

Кто-нибудь может подсказать мне, как это можно сделать? Я читаю материал о отложенных объектах jquery и обратных вызовах, но так как я не силен в jquery/js, я не могу его взломать. Js выполняется асинхронно, и поэтому все запросы изображений выполняются один за другим, и я не могу заставить j ждать, пока изображения для каждой строки не будут полностью обработаны перед отправкой следующей строки.

В настоящее время у меня есть цикл for и изображения в следующем формате:

$j("#thumbnail_image_"+i).css({'background-image':'url('+cdnPath+')'});
myImage[i].src = cdnPath;

2 ответа

Если вы хотите сделать это с отсрочкой / обещанием, то вы можете сделать это следующим образом:

$(function() {
    function loadRow($imgs, timeout) {
        var dfrd = $.Deferred(),
            n = 0;
        $imgs.each(function() {
            this.onload = function() {
                if(++n == $imgs.length) { dfrd.resolve(); }
            }
            this.src = "/path/to/img";
        });
        setTimeout(dfrd.resolve, timeout);//in case of slow network or img.onload failure
        return dfrd.promise();
    }

    var $images = $(img.whatever),//adjust as required
        rowlength = 5,//adjust as required
        rowFilter = function(i) {
            return function(index) {
                return (index > i * rowlength) && (index < (i+1) * rowlength);
            }
        },
        nRows = Math.ceil($images.length / rowlength);
        timeout = 10000,//(ms) adjust as required
        d = $.Deferred().resolve();
    for(var i=0; i<nRows; i++) {
        var $imgs = $images.filter(rowFilter(i));
        d = d.then(loadRow($imgs, timeout));
    }
});

непроверенной

loadRow() загружает строку и возвращает Обещание, которое разрешается при загрузке строки или времени ожидания.

Остальная часть кода:

  • устанавливает средства для изображений, которые будут выбраны по индексу строки.
  • устанавливает отсроченное начальное число, которое разрешается немедленно, чтобы начать процесс загрузки.
  • устанавливает пару других варов.
  • петли по строкам .then() цепь, которая вызывает loadRow() как это прогрессирует.

.then() Цепочка - это механизм, который контролирует последовательность загрузки строк.

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

По сути, если вы используете надлежащий элемент IMG для хранения изображения, вы можете подписаться на его события onload и onerror. Тогда вы можете посчитать, сколько изображений уже загружено

var loaded = 0;
for (var i = 0; i < imgtags.length; i++) {
   imgtags[i].src = "/path/to/img";

   function handle() {
       loaded++;
       if (loaded == imgtags.length) {
           loaded = 0;
           // call next row or finish
       };
   };
   img.onload = handle;
   img.onerror = function () { 
       handle(); 
       // possible error handling here
   };
};

где imgtags - массив с элементами IMG в текущей строке. Не забудьте установить счетчик на 0 в каждой строке. Поэтому вам не нужен JQuery для этого.

Если вы не используете элемент IMG и не устанавливаете фон для div, я не думаю, что это возможно.

демонстрация

Другие вопросы по тегам