Jquery 对AJAX请求集进行排队,并在一个队列中执行响应数据

Jquery 对AJAX请求集进行排队,并在一个队列中执行响应数据,jquery,Jquery,我有一组嵌套的Ajax调用,这些调用从服务器检索各种数据,并根据这些数据的结构更改一组页面元素,可能执行更多调用并更改更多元素,所有这些都是为了为用户生成新视图: $.ajax( //... function() { if(x) { $('#element').html('...'); } else { $.ajax(// more similar changes, more ajax)

我有一组嵌套的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,我可以设想三个选项:

  • 累积客户端的零碎数据,并在完成后对其进行操作
  • 在服务器端编写整个数据集,一次完成交付,然后执行操作
  • 当数据到达时,通过更新相关DOM片段的克隆来对零碎数据进行操作,然后在所有数据交付后切换DOM
  • 你选择哪个选项部分取决于你已经写了什么。从你在问题中所说的,最有吸引力的选择是#3


    您最大的问题可能是确定数据收集何时完成。

    您是否可以使用
    .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);
        });
    }