如果存在,则插入图像的ajax回调

时间:2014-07-07 08:49:43

标签: javascript jquery ajax asynchronous callback

我一直在关注this回答以尝试编写好的异步js - 但我无法弄清楚我的错误。

我使用自动完成功能从服务器请求一组特定文件,但对于某些数据集,这些文件可能不存在(即,可能有一个或最多四个文件)。如果它们确实存在,我想附加.html来包含它们。

除非我添加

,否则图片不会加载
  

async:false

到.ajax调用,这使得回调变得多余。

for (var i = 1; i < 5; i++) {
  (function (counter) {
    // define function with the callback argument
    function ajaxTest(callback) {
      $.ajax({
        type: "GET",
        url: counter + "_1.jpg",
        success: function (result) {
          callback(counter);
        }
      });
    }
    // call the function
    ajaxTest(function (num) {
      var image_temp = '<div class="thumbnail"> <img class="img-thumbnail" src="'+ num + '_1.jpg" /> Image' + num + '</div>';
      console.log(image_temp); //check readout
      image_html += image_temp;
    });
  })(i);
}

然后image_html仅包含存在的图像的html。

  

$(&#39; #outputcontent&#39;)。html(outer_html + image_html + outer_html_end);

有人能解释一下我的误会吗?为什么没有填充image_html?

编辑:&#39;完整&#39;代码如下。我使用jquery自动完成从stellar_comp数组中提取,然后对于那些存在属性(有些是空白的),生成html。其中就是ajax调用。

$(function () {
 var stellar_comp = [
     {
         value:'X0005-28',
         data: {
             set0: {
                 aperture:'X2105-28',
                 secat:'X025-18',
                 set:'1',
                 run:'r06',
                 continuumFilter:'J',
                 narrowBandFilter:'638/28',
                 numberOfSources:'1',
                 priorityCode:'1'
                    etc... etc ...
        },      
   },
 ];


 $('#autocomplete').autocomplete({
    lookup: stellar_comp,
    onSelect: function (suggestion) {


    var path_Value = 'data/' + suggestion.value + '/';
    var outer_html = '<h1>' + suggestion.value + ' </h1> <div class="container">';
    var outer_html_end = '</div>';


    for (var category in suggestion.data) {
        if (suggestion.data.hasOwnProperty(category)) {
            if (suggestion.data[category].aperture) {

                summary_table_contents = '<tr> <td>' + suggestion.data[category].set + '</td> <td>' + suggestion.data[category].run + '</td> <td>' + suggestion.data[category].continuumFilter + '</td> <td>' + suggestion.data[category].narrowBandFilter + '</td> <td>' + suggestion.data[category].numberOfSources + '</td> <td>' + suggestion.data[category].priorityCode + '</td></tr> ';

                summary_table += summary_table_contents;

                var aperturePlot = suggestion.data[category].aperture + '_' + suggestion.data[category].run;
                var seCATPlot = suggestion.data[category].secat + '_Rsub_ss_' + suggestion.data[category].run;
                var aperture_match = suggestion.data[category].aperture_match;


                cog = path_Plots + aperturePlot + '_cog';
                sbprof = path_Plots + aperturePlot + '_sbprof';
                thumb_cog = '';
                thumb_cog_temp = '';
                thumb_sb = '';
                temp='';
                for (var i = 1; i < 5; i++) {
                    (function (counter) {
                        function some_function(callback) {
                            $.ajax({
                                type: "GET",
                                url: cog + counter + "_1.jpg",
                                async: false,
                                success: function (result) {
                                    callback(counter);
                                }
                            });
                        }

                        some_function(function (num) {

                            var thumb_cog_temp = '<div class="col-lg-3 col-sm-4 col-xs-6"> <a class="thumbnail" target="_blank" href="' + cog + num + '_1.jpg"> <img class="img-thumbnail" src="' + cog + num + '_4.jpg" /></a> <div class="caption"><h5>' + suggestion.value + ':S' + num + '</h5></div></div>';
                            var thumb_sb_temp = '<div class="col-lg-3 col-sm-4 col-xs-6"> <a class="thumbnail" target="_blank" href="' + sbprof + num + '_1.jpg"><img class="img-thumbnail" src="' + sbprof + num + '_4.jpg" /></a><div class="caption"><h5>' + suggestion.value + ':S' + num + ' </h5></div></div>';
                            console.log(num, counter);
                            thumb_cog += thumb_cog_temp;
                            thumb_sb += thumb_sb_temp;
                        });
                    })(i);
                }


                cog_sbprofile_row='<div class="row"><h3>C o G</h3> ' + thumb_cog + '</div><div class="row"><h3>Profiles</h3>  ' + thumb_sb + '</div>';
                console.log(cog_sbprofile_row);
                body_html += aperture_row;
                body_html += seCAT_row;
                body_html += aperture_match_row;
                body_html += pixel_map_row;
                body_html += skyprofile_row;
                body_html += cog_sbprofile_row;
                body_html += '<hr>';
            };
        };
    };
    top_html += summary_table + '</tbody> </table> </div></div> <hr>';

    $('#outputcontent').html(outer_html +  hipass_container + top_html + body_html +  outer_html_end);

     }
 });

});

2 个答案:

答案 0 :(得分:0)

在所有ajax请求完成其作业后,您必须执行附加操作。首先定义一下:

var after = function(reqs) {
    var d = $.Deferred(),
        cnt = reqs.length;

    if (!cnt) {
        d.resolve();
    }

    var limit = cnt;  // separate var just in case reqs are synchronous
                      // so it won't mess up the loop

    for (var i = 0; i < limit; i++) {
        reqs[i].always(function() {
            cnt--;
            if (!cnt) {
                d.resolve();
            }
        });
    }
    return d.promise();
};

您可以使用$.when代替此,但如果其中一个请求导致404,则不会等待其他请求。现在:

var image_html = "",
    requests = [];

for (var i = 1; i < 5; i++) {
  (function (counter) {
    // define function with the callback argument
    function ajaxTest(callback) {
      return $.ajax({
        type: "GET",
        url: counter + "_1.jpg",
        success: function (result) {
          callback(counter);
        }
      });
    }
    // call the function
    var req = ajaxTest(function (num) {
      var image_temp = '<div class="thumbnail"> <img class="img-thumbnail" src="'+ num + '_1.jpg" /> Image' + num + '</div>';
      console.log(image_temp); //check readout
      image_html += image_temp;
    });

    requests.push(req);  // push the request to the array
  })(i);
}

after(requests).done(function() {
    $('#outputcontent').html(outer_html + image_html + outer_html_end);
});

请注意,我已添加return $.ajax(...)

BTW:定义ajaxTest功能的重点是什么?只需将所有内容放入匿名回调中即可。

在此处阅读有关延迟对象和承诺的更多信息:

http://api.jquery.com/category/deferred-object/

http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

或只是谷歌。

编辑:如果订单很重要,那么您只需稍微调整一下回调函数:

var image_html = [];  // array instead of string

// some code...

        var req = ajaxTest(function (num) {
            // ...
            image_html[counter] = image_temp;
        });

// some code...
after(requests).done(function() {
    image_html = image_html.join("");
    $('#outputcontent').html(outer_html + image_html + outer_html_end);
});

答案 1 :(得分:0)

当前的问题是由于在通过多个异步调用创建之前使用生成的HTML字符串。您需要推迟该操作直到所有加载完成,或者更改情况以使其不依赖于最终完成(渐进式加载看起来更加繁忙)。

就个人而言,我只需在循环时为图像插入占位符,并在加载时插入每个。这样就保留了订单。您甚至可以在加载时对每个效果进行效果(淡入淡出等):

var wrapper = "";
for (var i = 1; i < 5; i++) {
  // Make a placeholder element for each image we expect
  wrapper += '<div class="thumbnail" id="thumb_' + i + '">'

  (function (num) {
    // call the function
    $.ajax({
      type: "GET",
      url: num + "_1.jpg",
      success: function (result) {
          var image_temp = '<img class="img-thumbnail" src="'+ num + '_1.jpg" /> Image' + num;
          // Insert new image into unique element and fade it in
          $('#thumb_'+num).append(image_temp).fadeIn(); 
      }
    });
  })(i);
}

// Append all placeholders immediately - these will be appended to as each image is loaded
$('#outputcontent').html(outer_html + wrappers + outer_html_end);

更新

正如Alnitak指出的那样,整个练习有点无意义,因为你忽略了从Ajax调用返回的结果,所以你不妨删除Ajax调用(它没有添加任何值)并简单地构建飞行中的图像元素服务器端:)