Wait until all ajax requests are done

前端 未结 4 502
半阙折子戏
半阙折子戏 2020-12-18 12:11

I need to wait until all my ajax functions are done, and then continue the exectution.

My particular case is that I need to translate some fields in a form before su

相关标签:
4条回答
  • 2020-12-18 12:37

    You can use callback

    function translate(..., callback) {
        $.ajax({
            ...
            success:function(data) {
                ...
                callback(data);
            }
        });
    };
    

    And pass your after ajax code to it

    $("#form").submit(function() {
        translatable_fields.each(function() {
            translate(..., function(result){
    
                if (!(this).hasClass('ready')) {
                    $.ajax({
                        //validation
                        success: function(data) {
                            if (data['isValid']) {
                                $("#form").addClass('ready');
                                $("#form").submit();
                            }
                        }
                    });
                }
                return true;
            });
        });
    });
    
    0 讨论(0)
  • 2020-12-18 12:46

    You can achieve this in a much neater fashion using the deferred objects returned from a $.ajax call. First you should get the translate() function to return the deferred:

    function translate(...){
        return $.ajax({
            // settings...
        });
    });
    

    Then you can put all those promises in to a single array:

    var requests = [];
    translatable_fields.each(function(){
        requests.push(translate(...));
    });
    

    Then you can apply that array to $.when:

    $.when.apply($, requests).done(function(schemas) {
         console.log("All requests complete");
        // do something...
    });
    
    0 讨论(0)
  • 2020-12-18 12:46

    No, you can't just loop like this: the callbacks would never get a chance to be called.

    I would do something like this:

    function translateAllFields(done) {
        var requestsInProgress = 0, doneCalled = false;
        translatable_fields.each(function () {
            ++requestsInProgress;
            $.ajax({
                //...
                success: function (data) {
                    //...
                    $("#ajacCounter").val(parseInt($("#ajaxCounter").val()) - 1);
                }
            }).always(function () {
                if (--requestsInProgress === 0) {
                    done();
                    doneCalled = true;
                }
            });
        });
        if (requestsInProgress === 0 && !doneCalled) {
            // in case translatable_fields was empty
            done();
        }
    }
    

    and then:

    $("#form").submit(function (e) {
        if (!(this).hasClass('ready')) {
            e.preventDefault();
            e.stopPropagation();
            translateAllFields(function() {
                $.ajax({
                    //validation
                    success: function (data) {
                        if (data['isValid']) {
                            $("#form").addClass('ready');
                            $("#form").submit();
                        }
                    }
                });
            });
        }
    });
    
    0 讨论(0)
  • 2020-12-18 12:54

    You can do this using deferred objects, but you do not need to use $.when.apply with an array if you are only interested in the final completion.

    Instead you can chain parallel promises using the pattern promise = $.when(promise, another promise)

    Change your translate to return the Ajax promise:

    function translate(...) {
        ...
        return $.ajax({
            ...
        });
    }
    

    and your promise loop simply becomes:

    var promise; // Start with an undefined promise - which is the same as a resolved promise for $.when
    translatable_fields.each(function() {
        promise = $.when(promise, translate(...));
    });
    
    // Wait for all promises to complete
    promise.done(function(){
        // now do the final code after all the ajax calls complete
    });
    

    Notes:

    • This does create an extra promise per call to $.when, but the overhead is very small and the resulting code is quite simple.
    0 讨论(0)
提交回复
热议问题