等待Json内容被推送到数组。然后追加

时间:2017-09-08 13:13:22

标签: jquery html json

我有一个ajax函数,它加载由另一个ajax函数调用的缩略图,并从循环中获取参数。

我已经尝试使用.done和.ajaxComplete等待ajax调用完成,但是当ajax仍在调用时,该函数似乎仍然会触发。

但似乎在Ajax最后一次调用之前,数组是未定义的。

这是一个codePen - https://codepen.io/anon/pen/oermYj

//POPULATE IFRAMES FUNCTION
var counter = 0,
mainTitle,
iframeLink,
slideIndex,
iframeID,
iframeCount,
iframeTotal,
iframeTitles,
iframeThumbnail;
var iframeTitleArray = [];

function getIframeInfo(uniqueID){
  $.ajax({
    url: 'http://query.yahooapis.com/v1/public/yql',
        data: {
            q: "select * from json where url ='https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=" + uniqueID + "&format=json'",
            format: "json"
        },
        dataType: "jsonp",
    success: function (data) {
        iframeTitles = data.query.results.json.title;
    },
    error: function (result) {
        alert("Sorry no data found.");
    }
}).done(function pushTitles(){
  iframeTitleArray.push(iframeTitles);
});
}
console.log(iframeTitleArray);

function populateCars(carId){
  $.ajax({
    type : 'GET',
    url : 'json/data2.json',
    data : {
      get_param: 'value'
    },
    dataType : 'json',
    success : function(data){
      //DEFAULT DATA PLACEMENT
      $('.gallery-slider').empty();
      $('.gallery-sub-slider').empty();
      $('.grid-center-wrap').empty();

      //LOOP THROUGH JSON AND POPULATE
      $.each(data.iframeImages, function(i){
        iframeThumbnail = data.iframeImages[i].iframeThumb;
        iframeLink = data.iframeImages[i].iframeLink;
        iframeID = data.iframeImages[i].iframeID;
        iframeCount = i + 1;
        $('.gallery-slider').append('<iframe width="590" height="950" src="' + iframeLink + '" frameborder="0" allowfullscreen></iframe>');
        $('.grid-center-wrap').append('<div class="grid-block"><img class="grid-img" src="//img.youtube.com/vi/' + iframeThumbnail + '/0.jpg"><div class="grid-overlay" data-slick-index="' + i + '"></div><div class="grid-number">' + (iframeCount + ' / ' + data.iframeImages.length) + '</div></div>');
        $('.gallery-mobile-slider').append('<div><img src="//img.youtube.com/vi/' + iframeThumbnail + '/0.jpg" class="mobile-gallery-img" data-slick-index="' + i + '"></div>');
        getIframeInfo(iframeThumbnail);
      });

      //DEFAULT IMAGE COUNTER VALUE
      $('.slider-count').html('1' + ' / ' + iframeCount);

      //WORKING OUT SUB-GALLERY DIV AMOUNT, POPULATE
      var divCount = Math.ceil(data.iframeImages.length);

      for (var i = 0; i < divCount; i=i+2) {
        if(data.iframeImages[i+1] == undefined){
          console.log('not here');
          $('.gallery-sub-slider').append(`<div class="sub-gallery-item" data-slick-index="${i}"><img src="//img.youtube.com/vi/${data.iframeImages[i].iframeThumb}/0.jpg" class="sub-gallery-img" data-slick-index="${i}"></div>`);
          return;
        }
        else{
          $('.gallery-sub-slider').append(`<div class="sub-gallery-item" data-slick-index="${i}">
          <img src="//img.youtube.com/vi/${data.iframeImages[i].iframeThumb}/0.jpg" class="sub-gallery-img" data-slick-index="${i}">
          <img src="//img.youtube.com/vi/${data.iframeImages[i + 1].iframeThumb}/0.jpg" class="sub-gallery-img" data-slick-index="${i + 1}">
          </div>`);
        }
      }
      
    }
  }).done(function(){
    //INITIALIZE SLIDERS
    createSlider();
  });
}
populateCars();

3 个答案:

答案 0 :(得分:0)

尝试使用回调

   var something= FunctionWithCallback(data.property, function 
      callback(data) { do something, append to array })

     function FunctionWithCallback(passin, callback) {                    
                $.ajax({
                    url: "/controller/action",
                    type: "POST",
                    dataType: "json",
                    data: { passin: passin },
                    success: function(data) {
                        callback(data);
                    },

                });
            }

答案 1 :(得分:0)

您的主要问题是如何在ajax调用中指定 dataType

dataType: "jsonp",

将其更改为

dataType: "json",

顺便说一下,从回调中记录对象,而不仅仅是“它不起作用”的文本。你可以通过排除诊断来节省很多时间。

这是脚本工作的plnkr

答案 2 :(得分:0)

请记住,AJAX本质上是异步的:因此,当调用populateCars()方法并返回成功时,您将使用$.each()执行迭代。一切都很好,直到你遇到getIframeInfo()。此时,您正在进行另一个AJAX调用,但不等待它完成。解决问题的更简单方法是:

  1. getIframeInfo()
  2. 返回承诺
  3. getIframeInfo(iframeThumbnail)内的每次迭代中解决populateCars()的承诺时,您将检索到的所有数据推送到iframeTitleArray
  4. 您的代码的重构版本,删除所有不必要的代码以保持简单,将如下所示:

    function getIframeInfo(uniqueID) {
      // Return the promise
      return $.ajax({
        url: 'http://query.yahooapis.com/v1/public/yql',
        data: {
          q: "select * from json where url ='https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=" + uniqueID + "&format=jsonp'",
          format: "jsonp"
        },
        dataType: "jsonp"
      })
    }
    
    function populateCars(carId) {
      $.ajax({
        type: 'GET',
        url: 'https://api.myjson.com/bins/i80y1',
        data: {
          get_param: 'value'
        },
        dataType: 'jsonp'
      }).done(function(data) {
        //DEFAULT DATA PLACEMENT
        // ...
    
        //LOOP THROUGH JSON AND POPULATE
        $.each(data.iframeImages, function(i) {
    
          // ITERATIVE LOGIC
          // ...
    
          // Wait for getIframeInfo() to resolve, then push data into array
          getIframeInfo(iframeThumbnail).done(function(data) {
            var iframeTitle = data.query.results.json.title;
            iframeTitleArray.push(iframeTitle);
          })
        });
    
        // DEFAULT IMAGE COUNTER VALUE
        // ...
    
        // WORKING OUT SUB-GALLERY DIV AMOUNT, POPULATE
        // ...
      });
    }
    

    但是,根据您的代码,我没有看到您在其他地方使用iframeTitleArray。如果你真的想在某个时刻恢复完整的阵列,你将不得不菊花链接你的承诺。使用$.each()代替$.map(),以便将每个返回的getIframeInfo承诺推送到数组中,然后等待该数组中的所有承诺完全解析:

    // LOOP THROUGH JSON AND POPULATE
    var iframeTitles = $.map(data.iframeImages, function(i) {
    
      // ITERATIVE LOGIC
      // ...
    
      // Push getIframeInfo() to array
      return getIframeInfo(iframeThumbnail);
    });
    
    // Wait for all iframeTitles to be resolved
    $.when.apply($, iframeTitles).then(function() {
      var responses = arguments,
          titles = [];
    
      $.each(responses, function(idx, response) {
        var iframeTitle = response[0].query.results.json.title;
        titles.push(iframeTitle);
      });
    
      console.log(titles);
    });