jQuery Ajax竞争条件?

时间:2013-03-07 17:15:58

标签: javascript ajax jquery

我有以下JavaScript代码,它遍历页面上的文本字段列表。它将文本字段中的文本作为价格,通过AJAX GET将其发送到服务器,并从服务器获取解析后的双重结果。如果任何退回的价格低于现有价格,则表格不应提交。

问题是表单在所有AJAX请求完成之前提交,因为Ajax调用具有非阻塞的立即响应特性。我需要设置一个wait()函数(或者当所有Ajax方法完成时的回调),但不知道如何使用jQuery。

有什么建议吗?

// .submitForm is a simple button type="button", not type="submit"
$(".submitForm").click(function(e){
   var submittable = validatePrices();
   if (submittable) {
     $("#myForm").submit();
   }
});

function validatePrices() {
    var submittable = true; 

    $(".productPrice").each(function(){
        var $el = $(this);

        $.ajax({
            type: "POST",
            url: "/get_price.jsp", 
            async: false,
            dataType: "html",
            data: "price=" + $el.val(), 
            success: function(data)
            {                  
               var price = new Number(data.split("|")[1]);
               var minPrice = new Number($el.data("min-price")); 
               if (price < minPrice) 
               {
                  $el.addClass("error");
                  $(".dynamicMessage").show().addClass("error").append("<p>ERROR</p>");
                  submittable = false;
               }
            }
        });
        return submittable;
    });
}

2 个答案:

答案 0 :(得分:4)

您已经在使用同步AJAX(对您的用户体验来说是一个非常糟糕的主意),所以这不是问题所在。问题是您需要取消“提交”处理程序中的默认操作:

$(".submitForm").click(function(e){
   var submittable = validatePrices();
   e.preventDefault(); // this line
   if (submittable) {
     $("#myForm").submit();
   }
 });

对每个单独的字段使用同步HTTP请求返回服务器会使您的网站速度非常慢。无论如何,当您提交表单时,您将不得不再次检查服务器上的参数,因此最好只检查然后返回错误。

编辑 - 现在情况更清楚了,我认为继续进行的方法是完全停止进行AJAX验证检查。为什么?好吧,即使你执行这些测试,你仍然需要在实际提交表单时进行基本相同的有效性测试。您不能像任何其他表单验证方案那样依赖实际运行的JavaScript验证代码。如果您正在表单提交时进行验证,它将节省大量HTTP请求,以便同时完成所有操作。

答案 1 :(得分:1)

您没有取消表单提交。你必须严格使用ajax回调(如果你想异步使用它们,这将是不错的。)

$(".submitForm").click(function(e){
   e.preventDefault();
   validatePrices().done(function () { /* ajax success function here */
       if (submittable) {
           $("#myform").trigger('submit');
       }
   }
});

function validatePrices() {
    var checks = [];

    $(".productPrice").each(function(){
        var $el = $(this);
        checks.push($.ajax({
            /* snip */
    });
    return $.when.apply(null, checks);

}