2011-11-11 39 views
2

我有以下情况:我需要在循环中创建同步的Ajax请求,并在每次迭代之后在div元素中显示返回的结果(在顶部添加前面的结果底部)。每个请求的响应时间可能不同,但其显示顺序应与发布的相同。这里有3个请求的例子。假设请求“A”需要3秒,“B”需要1秒,“C”需要5秒。我想显示的结果的顺序是A,B,C作为请求发出,但我使用的代码示出了B,A的结果,C.在循环中使用JQuery同步Ajax请求

下面是代码(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调用完成并在循环后显示结果。我希望你们中的一些人能指出一些不同的解决方案,我几乎陷入困境。

在此先感谢, 干杯克里斯

编辑:感谢所有的可能的解决方案,我会尝试这些一一现在与一个适合我的问题回来。

+1

你不能使用回调或通过一个ID之后排序它们吗? AJAX当然是**异步** JavaScript和XML。 – Smamatti

+1

您将在等待结果时冻结用户界面** 8秒**?你不能认真。 –

回答

1

这会做的伎俩

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++); 
3

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

填充生成的div

您可以生成与IDS的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); 
      }); 
     } 
    }); 
}); 

第一种方法的优点是它可以持续填充容器。我还没有测试过这些功能,但逻辑应该按照我描述的方式工作。

0

我认为这就是你要找的东西。可能需要一些调整,我对延迟有点生疏。尽管如此,强大的威力

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()