等到所有ajax请求完成

And*_*mos 3 javascript forms ajax jquery

我需要等到我的所有ajax函数完成后再继续执行exectution.

我的具体情况是我需要在提交之前翻译表单中的某些字段.我通过对外部站点的ajax调用来翻译它们.根据表单中的某些值,我需要做更多或更少的翻译.完成所有翻译后(如果有的话)我必须用ajax验证表单,如果有效,则提交.

这是我的方法:
首先,我有一个函数发送ajax调用并对收到的数据做一些事情:

function translate(...) {
    $("#ajaxCounter").val(parseInt($("#ajaxCounter").val()) + 1);
    $.ajax({
        ...
        success:function(data) {
            ...
            $("#ajacCounter").val(parseInt($("#ajaxCounter").val()) - 1);
        }
    });
Run Code Online (Sandbox Code Playgroud)

然后,当要提交表单时,我执行以下代码:

$("#form").submit(function() {
    translatable_fields.each(function() {
        translate(...);
    });
    while (parseInt($("#ajaxCounter").val()) > 0) { null; }
    if (!(this).hasClass('ready')) {
        $.ajax({
            //validation
            success: function(data) {
                if (data['isValid']) {
                    $("#form").addClass('ready');
                    $("#form").submit();
                }
            }
        });
    }
    return true;
});
Run Code Online (Sandbox Code Playgroud)

问题是while提交函数中的循环永远不会结束.

如果我在没有while循环的情况下执行代码,我可以看到ajaxCounter输入在翻译函数开始时增加,在结束时减少.

Ror*_*san 13

您可以使用deferred$.ajax调用返回的对象以更整洁的方式实现此目的.首先你应该得到translate()函数返回deferred:

function translate(...){
    return $.ajax({
        // settings...
    });
});
Run Code Online (Sandbox Code Playgroud)

然后你可以把所有这些承诺放在一个数组中:

var requests = [];
translatable_fields.each(function(){
    requests.push(translate(...));
});
Run Code Online (Sandbox Code Playgroud)

然后你可以apply将该数组$.when:

$.when.apply($, requests).done(function(schemas) {
     console.log("All requests complete");
    // do something...
});
Run Code Online (Sandbox Code Playgroud)

  • 这是一个优雅的解决方案 (2认同)