Multiple ajax calls inside a each() function.. then do something once ALL of them are finished?

百般思念 提交于 2019-11-26 16:42:15

Use deferred objects:

$("#form").submit(function(e){

    e.preventDefault();

    var calls = [];

    $(".friendName[value!='']").each(function(){
        // Submit the ajax request
        calls.push($.ajax({ 
            type: 'POST', 
            url: 'ajax/url', 
            data: {
                name: name,
                email: email
             },
             success: function(json) {
                // Log a console entry if our ajax request was successful
                console.log(name + " was submitted via ajax");
             }
         }));
    });

    $.when.apply($, calls).then(function() {
        window.location= '/thanks';
    });
});

Ok, this is fairly easy since you're using jQuery. jQuery comes with an integrated promise maker which also is wired up with jQuery's Ajax calls. What does that mean? Well, we can easily go like this:

var requests = [ ];

// ...

// Submit the ajax request
requests.push($.ajax({ 
    type: 'POST', 
    url: 'ajax/url', 
    data: {
        name: name,
        email: email
    },
    success: function(json) {
        // Log a console entry if our ajax request was successful
        console.log(name + " was submitted via ajax");
    }
}));

// at this point we filled our array with jXHR objects which also inherit the promise API

$.when.apply( null, requests ).done(function() {
    document.location.href = '/thanks';
});

Note: The above code will only fire, if all requests completed successfully. If you need to handle the case if one ore more requested failed, use .then() or .fail() instead of .done(), too.

Just keep a counter of the AJAX calls and check to see when they have all completed. Something like this:

$("#form").submit(function(){
    var ajaxMax = $(".friendName[value!='']").length, ajaxCounter = 0;
    $(".friendName[value!='']").each(function(){
        var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
        if($("#"+idEmail+"[value!='']").length > 0){
            var name = $(this).val();
            var email = $("#"+idEmail).val();

            // Submit the ajax request
            $.ajax({ 
                type: 'POST', 
                url: 'ajax/url', 
                data: {
                    name: name,
                    email: email
                },
                success: function(json) {
                    // Log a console entry if our ajax request was successful
                    console.log(name + " was submitted via ajax");
                    if(++ajaxCounter >= ajaxMax)
                        window.location= '/thanks';
                }
            });
        }
    });
});

By default $.ajax is asynchronous. In the options hash being passed, add

async: false

That will serialize the calls you are making having it perform the way you want.


After getting comment from original poster, possible solution may be to do the following:

  • Inside the submit call determine the number of calls that should be made.
  • Store this result as a local variable within the handler function
  • Create a callback on 'complete:' that will examine the value of the calls
    • If the number of calls to be made is greater than 0, then decrement the value and return
    • If the number of calls reaches zero, update the window.location (really should use window.location.href as window.location is an object but browsers will allow this and perform correctly)

Note, I don't have any information on the thread safety of performing this kind of operation so YMMV.


Example Code:

$("#form").submit(function(eventObject){
    var $ajaxFields= $(".friendName[value!='']").filter(function(index){
        var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
        return ($("#"+idEmail+"[value!='']").length > 0);
    });

    var numberToSubmit= $ajaxFields.length;
    $ajaxFields.each(function(){
        var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
        var name = $(this).val();
        var email = $("#"+idEmail).val();

        // Submit the ajax request
        $.ajax({ 
            type: 'POST', 
            url: 'ajax/url', 
            data: {
                name: name,
                email: email
            },
            success: function(json) {
                // Log a console entry if our ajax request was successful
                console.log(name + " was submitted via ajax");
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log("call not completed: "+textStatus);
            },
            complete: function(jqXHR, textStatus) {
                if( --numberToSubmit == 0 ) {
                    window.location.href= '/thanks';
                }
            }
        });
    });

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