在所有产品都已加载时使用延迟

时间:2015-08-27 23:45:45

标签: javascript jquery ajax jquery-deferred

我有一个带旋转木马的页面,每次幻灯片更改时都会发送一个ajax请求,并生成与幻灯片相关的产品到底部的另一个旋转木马。

在每张幻灯片发生变化时,使用Ajax成功绘制产品,但是一旦加载了ajax请求,我需要使用产品启动滑块。现在,滑块尝试在请求完成之前初始化。

在我添加的代码的底部,每个函数将每个getProducts函数添加到一个数组,然后在完成后,它应该初始化滑块。虽然在控制台中消息'this is initialized'发生在Ajax请求中的'success'消息之前。

我是否在此示例中使用了延迟错误导致此问题?

        var products = [],
        uniqueProducts = [], 
        defs = [];           
        var el;
        $('.your-class [data-slick-index="' + currentSlide + '"] a').each(function(i) { 
              el = $(this).attr("href");      
              products.push(el);
              $.each(products, function(j, el) {
                  if ($.inArray(el, uniqueProducts) === -1)
                      uniqueProducts.push(el);
                      console.log("pushed" + uniqueProducts);
              });
        });
        function getProducts(el) {
          var def = new $.Deferred(); 
          var url = el;

          $.get(url, function(data) {  
                var imageArray = data.match(/<img itemprop="image" [\S\s]*?>/ig);
                var $image = $(imageArray[0]);
                var imageUrl = $image.attr('src');
                var name = $image.attr('title');
                var priceArray = data.match(/<p class="price">[\S\s]*?<\/p>/ig);
                var priceEl = $(priceArray[0]).find('[itemprop=price]');
                priceEl.children().remove();
                var price = priceEl.text() ? '$' + priceEl.text() : '';
                $( ".carousel2" ).append( '<div><img src=\" '+ imageUrl +'\"></div>');
                console.log("success");
                def.resolve();
          });
          return def.promise();
        }

      $.each(uniqueProducts, function(i, el) {
          defs.push(getProducts(el));
      });

      $.when($,defs).done(function () {
          $('.carousel2').slick({ speed: 500, autoplay: false, autoplaySpeed: 4000, arrows:false });
          console.log("this is initialized");
      });           
    } 

2 个答案:

答案 0 :(得分:0)

我暂时没有使用$.when,但我认为您可以在不创建$.Deferred()个实例的情况下使其工作,因为$.get会为您返回此内容。

可能会尝试getProducts返回$.get而不是def.promise,并取消对def的任何引用?

希望能帮到你!

p.s我搜索了一些旧的代码,我使用了$.when来查看我如何将它与$.get一起使用。我已经对它进行了简化,并且以下内容应该有效。

$.when([
  $.get("data/a.json"),
  $.get("data/b.json"),
  $.get("data/c.json")
]).done(function (t1, t2, t3) {
  app.a = t1[0];
  app.b = t2[0];
  app.c = t3[0];
});

答案 1 :(得分:0)

归功于this answer,构建[4,5]将简化为两个单行。

3

4应简化如下:

5

请注意,uniqueProducts现在没有副作用,但会返回一个数据对象。

然后,使用var uniqueProducts = $('.your-class [data-slick-index="' + currentSlide + '"] a').map(function(el) { return $(el).attr('href'); }).get().filter(function(href, pos, self) { return self.indexOf(href) == pos; }); ,您可以致电getProducts() 处理承诺提供的数据。

假设一切都发生在一个函数中,你最终会得到这样的结果:

function getProducts(url) {
    return $.get(url).then(function(data) {
        var image = $(data.match(/<img itemprop="image" [\S\s]*?>/ig)[0]);
        var price = $(data.match(/<p class="price">[\S\s]*?<\/p>/ig)[0]).find('[itemprop=price]').children().remove().end().text();
        return {
            name: image.attr('title'),
            image: image,
            price: price ? '$' + price : ''
        };
    });
}

这种特殊的.reduce模式的特点是:

  • ajax调用并行
  • 如果需要,可以非常简单地转换串口呼叫。
  • 附加到轮播的图像顺序将与缩小的数组一致,即“正确的顺序”。
  • 任何个人的ajax错误都不会破坏整个企业。
  • 不需要中间getProducts()数组或jQuery的繁琐uniqueProducts.reduce(...)(或其他lib中更友好的getProducts()。)