Jquery 对AJAX请求集进行排队,并在一个队列中执行响应数据
我有一组嵌套的Ajax调用,这些调用从服务器检索各种数据,并根据这些数据的结构更改一组页面元素,可能执行更多调用并更改更多元素,所有这些都是为了为用户生成新视图:Jquery 对AJAX请求集进行排队,并在一个队列中执行响应数据,jquery,Jquery,我有一组嵌套的Ajax调用,这些调用从服务器检索各种数据,并根据这些数据的结构更改一组页面元素,可能执行更多调用并更改更多元素,所有这些都是为了为用户生成新视图: $.ajax( //... function() { if(x) { $('#element').html('...'); } else { $.ajax(// more similar changes, more ajax)
$.ajax(
//...
function() {
if(x) {
$('#element').html('...');
} else {
$.ajax(// more similar changes, more ajax)
}
}
)
目前,上述代码导致按顺序重新绘制元素。但是,我希望所有的重画都能一次完成——至少从用户的角度来看是这样的——这样用户只会体验到平滑过渡到新视图的过程,而不会看到单独的渲染
如果不取决于每个请求的具体响应,我如何实现这一点 jQuery有一个
.when()
和.done()
函数,在您的例子中,它将首先执行所有AJAX请求,当所有请求完成时,您可以一次性处理所有响应数据,因此用户不会看到不同AJAX请求在不同阶段完成时的交错转换
$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
// the code here will be executed when all four AJAX requests complete
// a1, a2, a3 and a4 contain lists of 3 items; the response text [0],
// the status [1], and an jqXHR object [2] for each of the listed AJAX calls
$('#element1').html(a1[0]);
$('#element2').html(a2[0]);
$('#element3').html(a3[0]);
$('#element4').html(a4[0]);
});
function ajax1() {
return $.ajax({
url: "someUrl.php",
dataType: "html",
data: myData,
...
});
}
function ajax2() {} // same as above
function ajax3() {} // same as above
function ajax4() {} // same as above
有关使用.when()
的更多信息,以及如何错误处理AJAX调用,请查看
如果您取决于每个请求的具体响应
您可以将每个响应和元素ID存储到一个数组中,并在所有AJAX调用完成后一次性处理它们。类似的内容可能会有所帮助(使用上面的代码):
下面是一个演示阵列想法的示例。Chrsva,我可以设想三个选项:
您最大的问题可能是确定数据收集何时完成。您是否可以使用
.ajaxStop(function(){})
来确定所有AJAX调用何时完成,然后切换DOM?我从来都不需要使用.ajaxStop()
,并且会担心,在这种情况下,它可能会过早启动,但值得一试。我从您的问题中删除了[jQuery Animate]和[jQuery Deferred]标记,因为我认为它们无关紧要。也使标题看起来更可读和更可搜索。不幸的是,我确实依赖于它们-它们调用是嵌套的,并且根据每次在服务器上戳的结果生成。因此,当我调用链的顶端时,我无法知道总共将调用哪些Ajax调用或调用多少Ajax调用—因此,我需要一种方法来收集所有调用,然后再进行渲染。@chrsva;哦,好吧,没关系。我将把这个答案留在这里,因为它可能会帮助其他人。另一项建议;您可以将每个响应存储在数组{elementID,responseData}
中,并且在所有AJAX调用完成后$(document).ajaxStop(executeMyResponses())
在数组中循环,将每个响应数据添加到相应的元素中。谢谢,我将检查它@chrsva我在我的答案中添加了一个扩展,其中包含我的数组建议。
var myAjaxResponses = [];
$.ajax(
//...
function() {
if(x) {
myAjaxResponses.push({
'elementID': "element1",
'responseData': x,
});
} else {
$.ajax(
function() {
if (x) {
myAjaxResponses.push({
'elementID': "element2",
'responseData': x,
});
}
}
)
}
}
)
// loop through myAjaxResponses
// adding the response data to each respective element
function processResponses() { // called when last AJAX request finishes
$.each(myAjaxResponses, function (index, value) {
$('#'+value.elementID).html(value.responseData);
});
}