How do you use .when().then() to trigger a function when using deffered objects in the .when()?

自作多情 提交于 2020-01-01 12:31:22

问题


I have a page in which I have a variable number of AJAX calls to make which are triggered on a common event. The AJAX calls themselves are to update related fields in a SQL database. Once all the calls are complete, I want to refresh the page so that it now reflects the changes just made.

I used the following question/answer on here to get so far.. jQuery when each is completed, trigger function

Here is my code so far:

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

}

What I was expecting to happen, is that the $('#content-wrapper').load( 'index.php' ); would fire, once all my ajax() requests had completed. What appears to be happening though, is that the callback is firing once all the requests have been sent, not necessarily after they have completed, and so sometimes my page update still has 'old' data on it.

The graphic below shows my initial page load at the top, which can be ignored. Its the next 4 entries that show the issue. There are 3 POST requests which are my 3 ajax calls to update the DB, and the final GET which is the page refresh. The Page refresh GET fires after all 3 ajax calls have been sent, but it doesn't wait for the last ajax call to complete before it fires. As a consequence, it then gets old data as it completes before the previous ajac call has finished updating the database.

What am I doing wrong here?


回答1:


I recently applied something similar.

when() expects a deferred object or list of deferred objects, but if you want to use an array, you need to use apply().

replace

$.when(XHRs)

with

$.when.apply(null, XHRs)

If this does not work, you might need to wrap your Ajax call in a function:

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

and then push them to XHRs as such:

XHRs.push(SendAjax(data));

the following is how I implemented this in my code, you can adapt this if needed:

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

And yes, the comments are actually in my code and not just added for clarification on this page.



来源:https://stackoverflow.com/questions/24306790/how-do-you-use-when-then-to-trigger-a-function-when-using-deffered-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!