javascript - 每个带有 ajax 调用的 jQuery 将在完成之前继续

标签 javascript jquery ajax

我有一些 jQuery,它使用每个循环遍历在 Symfony 3 CRM 的重复表单字段中输入的值。有一个 $.post 将输入的值发送到一个函数,该函数检查数据库中的重复项,如果它是重复的,它会向数组添加一些内容,否则它会添加一个空白值以表明它是不是骗子。完成这些操作后,它会检查最终数组并将任何错误添加到错误 block 以显示给用户。

但是,该数组似乎总是空白,我相信这是因为它在实际完成获取响应之前运行显示错误的代码。

这是我的代码:

$('#puppy_form').on('submit', function() {
    var bitch_errors = [];
    var dog_errors = [];
    // NOTE: Bitch and dog names need to be checked differently so we know which error is assigned to which input
    $('.check_bitch_name').each( function(i, obj) {
        // need to check each name for validity and duplication.
        var entered_bitch_name = obj.value;
        var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
        if(!pattern.test(entered_bitch_name)) {
            bitch_errors[i+1] = "invalid";
        } else {
            // now to check for duplicates
            $.post('/check-puppy-name', { name: entered_bitch_name }
            ).done(function (response) {
                if(response == 'duplicate') {
                    bitch_errors[i+1] = "duplicate";
                } else {
                    bitch_errors[i+1] = "";
                }
            });
        }
    });
    $('.check_dog_name').each( function(i, obj) {
        // need to check each name for validity and duplication.
        var entered_dog_name = obj.value;
        var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
        if(!pattern.test(entered_dog_name)) {
            dog_errors[i+1] = "invalid";
        } else {
            // now to check for duplicates
            $.post('/check-puppy-name', { name: entered_dog_name }
            ).done(function (response) {
                if(response == 'duplicate') {
                    dog_errors[i+1] = "duplicate";
                } else {
                    dog_errors[i+1] = "";
                }
            });
        }
    });


    if(count(bitch_errors) == 0 && count(dog_errors) == 0) {
        return true;
    }

    // loop through the errors and assign them to the correct input
    $.each( bitch_errors, function( key, value ) {
        if (value == "invalid") {
            $('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
            $('input[name="bitch_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
            return false;
        } else if(value == "duplicate") {
            $('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
            $('input[name="bitch_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
            return false;
        }
    });
    $.each( dog_errors, function( key, value ) {
        if(value != "") {
            if (value == "invalid") {
                $('input[name="dog_name['+key+']"]').parent().addClass('has-error');
                $('input[name="dog_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
                return false;
            } else if(value == "duplicate") {
                $('input[name="dog_name['+key+']"]').parent().addClass('has-error');
                $('input[name="dog_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
                return false;
            }
        }
    });

    return false;

});

基本上,它首先检查输入的名称是否有效,然后发布并检查重复项。问题是,即使它进行了有效性检查(并相应地打印错误),它似乎也忽略了重复检查并在它甚至回调第一个响应之前继续进行。

在继续并将错误添加到表单之前,如何确保它已完成检查?我尝试过其他解决方案,包括尝试在 jQuery 中实现 $.when 功能,但我真的不明白如何让它工作。任何帮助表示赞赏。

最佳答案

首先,编写一个返回异步 promise 的函数,为您提供一只狗的值:

function checkDog(name) {
    var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
    if(!pattern.test(name)) {
        return $.Deferred().resolve("invalid");
    } else {
        return $.post('/check-puppy-name', { name: name } )
         .then(function (response) {
            if (response === 'duplicate') {
                return 'duplicate';
            } else {
                return '';
            }
        });
    }
}

然后你可以编写一个处理狗的程序,同时返回一个 promise (在检查每只狗之前不会自行解决):

function checkDogs(array) {
    return $.when.apply($, array.map(checkDog));
}

请注意,目前还没有与 DOM 相关的代码。您现在可以编写一个函数,从一堆 DOM 输入中获取值并将它们返回到一个数组中:

function getInputValues($selector) {
    return $selector.get().map(function(el) {
        return el.value;
    });
}

现在(在提交上)您可以检查您的两组输入,最后当这两组输入都可用时,您可以检查结果并更新 DOM:

$('#puppy_form').on('submit', function() {

    var bitch_names = getInputValues($('.check_bitch_name'));
    var dog_names = getInputValues($('.check_dog_name'));

    var bitch_promises = checkDogs(bitch_names);
    var dog_promises = checkDogs(dog_names);

    $.when(bitch_promises, dog_promises).then(function(bitch_errors, dog_errors) {
        // update the DOM based on the passed arrays
        ...
    });
});

关于javascript - 每个带有 ajax 调用的 jQuery 将在完成之前继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41716154/

相关文章:

ajax - 从 Magento Admin Extension 输出 ajax 数据的最佳方式

javascript - 将 HTML 标签的内容与 Javascript RegEx 进行匹配

javascript - 使用 emberjs 自动刷新模板

javascript - javascript 中特定键的返回值?

php - JSON 返回数组的奇怪结果

jquery - 通过 AJAX 提供 Fancybox

javascript - 使用 jQuery 动态填写表单值

javascript - 从 csv 文件中排除显示的某些值

jQuery 在隐藏时停止 HTML5 视频,在可见时重新启动

jquery - 自动填充时扩展搜索栏关闭