【问题标题】:How do you use .when().then() to trigger a function when using deffered objects in the .when()?在 .when() 中使用延迟对象时,如何使用 .when().then() 触发函数?
【发布时间】:2014-06-19 21:15:40
【问题描述】:

我有一个页面,其中我有可变数量的 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 是页面刷新。页面刷新 GET 在所有 3 个 ajax 调用都发送后触发,但它不会等待最后一个 ajax 调用完成后再触发。因此,它会在之前的 ajac 调用完成更新数据库之前获取旧数据。

我在这里做错了什么?

【问题讨论】:

    标签: jquery ajax jquery-deferred


    【解决方案1】:

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

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

    替换

    $.when(XHRs)
    

    $.when.apply(null, XHRs)
    

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

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

    然后将它们推送到 XHR:

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

    是的,cmets 实际上在我的代码中,而不仅仅是为了在此页面上进行说明而添加的。

    【讨论】:

    • 看准了!我看到了另一篇关于使用 apply 的帖子,但我在 jQuery 文档中没有找到关于如何使用它的任何内容。 $.when.apply(null, XHRs) 工作愉快。谢谢。
    • 我只是注意到我的答案第一行中无意的双关语。
    猜你喜欢
    • 1970-01-01
    • 2014-05-28
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 2014-11-10
    • 2013-03-09
    相关资源
    最近更新 更多