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

时间:2014-06-19 12:36:12

标签: jquery ajax jquery-deferred

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

到目前为止,我在这里使用了以下问题/答案。 jQuery when each is completed, trigger function

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

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' );
    });

}

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

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

Firebug timeline

我在这里做错了什么?

1 个答案:

答案 0 :(得分:5)

我最近申请了类似的东西。

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

替换

$.when(XHRs)

$.when.apply(null, XHRs)

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

function SendAjax(data){
return $.ajax({Options as they are in your ajax call});
}

然后将它们推送到XHRs:

XHRs.push(SendAjax(data));

以下是我在代码中实现此功能的方法,如果需要,您可以对其进行调整:

//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});
}

是的,这些评论实际上是在我的代码中,而不只是为了澄清此页面而添加。