在.when()中使用deffered对象时,如何使用.when().then()来触发函数?

Boi*_*idy 4 ajax jquery jquery-deferred

我有一个页面,其中我有一个可变数量的AJAX调用,这些调用是在一个公共事件上触发的.AJAX调用本身是更新SQL数据库中的相关字段.完成所有调用后,我想刷新页面,以便它现在反映刚刚进行的更改.

我在这里使用了以下问题/答案到目前为止... jQuery当每个完成时,触发函数

到目前为止,这是我的代码:

var team_update = function(e) {
    var $items = $('.sortable-items');
    var XHRs = [];

    $items.each(function(){
        var team_id = $( this ).attr("id");
        var data =  {
            tid: team_id,
            users: $('#' + team_id).sortable('toArray')
            };

        XHRs.push(
            $.ajax({ 
                type: "POST", 
                url: "update.php", 
                data: data, 
                complete: function(data){
                } 
            })  
        );

    });

    $.when(XHRs).then(function(){
        console.log('Refreshing Screen');
        $('#content-wrapper').load( 'index.php' );
    });

}
Run Code Online (Sandbox Code Playgroud)

我期待发生的事情是$('#content-wrapper').load( 'index.php' );,一旦我的所有ajax()请求完成,就会触发.然而,似乎正在发生的事情是,一旦所有请求都已发送,回调就会触发,不一定在它们完成之后,因此有时我的页面更新仍然有"旧"数据.

下图显示了我在顶部的初始页面加载,可以忽略.显示该问题的接下来的4个条目.有3个POST请求是我的3个ajax调用来更新数据库,最后的GET是页面刷新.在发送了所有3个ajax调用之后,页面刷新GET将触发,但它不会等待最后一个ajax调用在它触发之前完成.因此,它会在前一个ajac调用完成更新数据库之前完成旧数据.

Firebug时间轴

我在这做错了什么?

Nza*_*all 5

我最近应用了类似的东西.

when()期望延迟对象或延迟对象列表,但如果要使用数组,则需要使用apply().

更换

$.when(XHRs)
Run Code Online (Sandbox Code Playgroud)

$.when.apply(null, XHRs)
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,您可能需要在函数中包装Ajax调用:

function SendAjax(data){
return $.ajax({Options as they are in your ajax call});
}
Run Code Online (Sandbox Code Playgroud)

然后将它们推送到XHRs:

XHRs.push(SendAjax(data));
Run Code Online (Sandbox Code Playgroud)

以下是我在代码中实现的方法,如果需要,您可以调整它:

//We want to notify how many memberships have been made after they're all made. since they're async, we'll need to use promises
//however, because we repeat the same ajax call with different parameters, we need to push them to an array and then apply() them.
checkedBoxes.each(function () {
    createArray.push(CreateMembershipsAjax(this));
});
//we did the work before we start creating them, so show some progress;
add1ToProgress();
$.when.apply(null, createArray).done(function () {
    //this function will only start once all ajax calls have been successfull.
    divCreated.append(membershipCount + " memberships created:");
    MembershipsCreated = true;
    window.close();
});

...

CreateMembershipsAjax(element){
    //process element, create Data from it;
    return $.ajax({option});
}
Run Code Online (Sandbox Code Playgroud)

是的,评论实际上是在我的代码中,而不仅仅是为了澄清这个页面而添加的.