我有以下情况:我需要在循环中发出同步的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()