Javascript 用于插入图像(如果存在)的ajax回调

Javascript 用于插入图像(如果存在)的ajax回调,javascript,jquery,ajax,asynchronous,callback,Javascript,Jquery,Ajax,Asynchronous,Callback,我一直在遵循这个答案,试图编写好的异步js——但我不太明白我到底出了什么问题 我使用autocomplete从服务器请求一组特定的文件,但对于某些数据集,这些文件可能不存在,即可能有一个或最多四个文件。如果它们确实存在,我想附加.html以包含它们 除非我添加,否则图像不会加载 异步:false 到.ajax调用,这使得回调是多余的 for (var i = 1; i < 5; i++) { (function (counter) { // define function wi

我一直在遵循这个答案,试图编写好的异步js——但我不太明白我到底出了什么问题

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

除非我添加,否则图像不会加载

异步: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

$'outputcontent'.htmlooter\uHTML+图像\uHTML+外部\uHTML\uEnd

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

编辑下面的“完整”代码。我使用jqueryautocomplete从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);

     }
 });

});

您必须在所有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();
};
注意,我添加了return$.ajax

顺便问一下:定义ajaxTest函数的意义是什么?把所有东西都放在匿名回拨中

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

或者只是谷歌一下

编辑:如果顺序很重要,则只需稍微调整回调函数:

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);
});

当前的问题是由于在通过多个异步调用创建结果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调用,只在动态服务器端构建图像元素:

您是否执行$'outputcontent';在所有异步任务完成之后?啊,我不知道-我该如何检查这一点?正如Chickencrence所建议的那样,没有代码显示会在尝试更新HTML之前等待所有异步Ajax调用完成。您需要显示代码的其余部分,以便在需要重新组织代码时提供解决方案。请注意,永远不要使用async:false。问:图像的显示顺序重要吗?它们需要按顺序加载还是按加载顺序加载?因为AJAX图像加载程序将异步加载图片,所以在将图片附加到容器DOM之前,您需要确保所有图片都已正确加载。您刚刚向新手描述了一个基于承诺的解决方案,但没有解释。你可能想详细解释一下。@TrueBlueAussie嗯,这是一个很大的话题。我添加了一些资源。希望这就足够了,我真的不想解释所有的细节。谢谢@freakish-看来我还有一天要阅读了。我想我看到了它是如何工作的。SO没有回答我的问题,但很可能图像显示顺序很重要,否则您可以在加载图像时附加每个图像,并忘记所有这些复杂性。如果顺序很重要,你的答案就不能解决整个问题。干杯。虽然是的,作为一个新手,我可能明天也会回来寻求帮助。感谢您迄今为止的投入。我对动态构建图像元素的建议有点困惑——正如我在原始帖子中所说,并不总是有四个图像。我如何知道一个图像是否存在,因此应该在不首先执行ajax请求的情况下显示?我喜欢fadeIn的想法,现在需要在包装器的末尾尝试一下,但是我已经开始工作了,我想我已经开始掌握闭包和范围了。非常感谢你的帮助@利兹·奥菲库斯:我应该解释得更清楚些。如果映像在服务器上,那么构建映像列表应该在服务器端完成,而不是在客户端完成。对本地服务器文件的所有Ajax请求都将被浏览器拉下来,这毫无意义。希望这一切都有帮助。
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);