在循环中使用JQuery同步Ajax请求



我有以下情况:我需要在循环中发出同步的Ajax请求,并在div元素中显示每次迭代后返回的结果(在顶部附加先前的结果在底部)。每个请求的响应时间可以不同,但显示的顺序应该与发出的顺序相同。下面是一个有3个请求的例子。假设请求"A"需要3秒,"B"需要1秒,"C"需要5秒。当请求发出时,我想要显示结果的顺序是A, B, C,但我使用的代码以B, A, C显示结果。

下面是代码(JQuery Ajax请求):
$(document).ready(function(){ 
  var json = document.getElementById("hCategories").value;
  var categories = eval( '(' + json + ')' );
  for(curCat in categories) {
    curCatKey = categories[curCat]['grKey'];
    $.ajax({
      type: "POST",
      url: "get_results.php",
      data: "category=" + escape(curCatKey) + 
            "&search=" + escape($("#hQuery").val()),
      timeout: 8000,
      async: false, 
      success: function(data) {
        $("#content").append(data);
      }
  });
});

我认为它会与"async:false"一起工作,但它会等到每个Ajax调用完成并在循环后呈现结果。我希望你们中的一些人能指出一些不同的解决方案,我被困住了。

提前感谢,欢呼声克里斯

编辑:感谢所有可能的解决方案,我会一个接一个地尝试这些,然后带着适合我问题的那个回来。

对于这个问题,我有两个解决方案:

填充生成的div

您可以在循环中生成带有id的div,并在请求完成时填充它们:

$(document).ready(function() {
    var json = document.getElementById("hCategories").value;
    var categories = eval('(' + json + ')');
    for (curCat in categories) {
        (function(curCat) {
            var curCatKey = categories[curCat]['grKey'];
            $('#content').append('<div id="category-"' + escape(curCat) + '/>');
            $.ajax({
                type: "POST",
                url: "get_results.php",
                data: "category=" + escape(curCatKey) + "&search=" + escape($("#hQuery").val()),
                success: function(data) {
                    $("#category-" + escape(curCat)).html(data);
                }
            });
        })(curCat);
    }
});

或者使用延迟的

您可以将jqXHR对象存储在数组中,并在所有调用完成后使用deferred来按顺序调用成功函数。

$(document).ready(function() {
    var json = document.getElementById("hCategories").value;
    var categories = eval('(' + json + ')');
    var requests;
    for (curCat in categories) {
        var curCatKey = categories[curCat]['grKey'];
        requests.push($.ajax({
            type: "POST",
            url: "get_results.php",
            data: "category=" + escape(curCatKey) + "&search=" + escape($("#hQuery").val())
        }));
    }
    $.when.apply(requests).done(function() {
        for (i in requests) {
            requests[i].success(function(data) {
                $("#content").append(data);
            });
        }
    });
});

第一个方法的优点是它连续地填充容器。我还没有测试过这两个函数,但是逻辑应该按照我描述的方式工作。

这就行了

var results = [];
var idx = 0;
for(curCat in categories) {
    curCatKey = categories[curCat]['grKey'];
    (function( i ) {
        $.ajax({
          type: "POST",
          url: "get_results.php",
          data: "category=" + escape(curCatKey) + 
              "&search=" + escape($("#hQuery").val()),
          timeout: 8000,
          async: false, 
          success: function(data) {
            results[i] = data;
            if (i == idx - 1) { // last one
               for (var j=0; j < results.length; j++) {
                   $("#content").append(results[j]);
               }
            }
          }
       });
    })(idx++);

我想这就是你要找的东西。可能需要调整一下,我对《延期》有点生疏了。尽管如此,仔细阅读它,强大的力量

deferred = $.Deferred()
for(curCat in categories) {
  deferred.pipe(
    function(resp){
      postData = {} // set up your data...
      return $.post("get_results.php", {data: postData, timeout: 8000})
              .done(function(content){ $("#content").append(content) })
    })
  )
}
// Trigger the whole chain of requests
deferred.resolve()

最新更新