在$.ajax中嵌套了$.ajax-非常奇怪的问题

nested $.ajax in inside $.ajax - very strange issue

本文关键字:问题 非常 ajax 嵌套 ajax-      更新时间:2024-02-01

让我们从这里开始-我已经为所有未来的AJAX请求定义了基本设置,比如这个

$.ajaxSetup({
  beforeSend : function(){
      $("#ajax-loader").dialog({
         modal : true 
      });
  },
  complete : function(){
     $("#ajax-loader").dialog("hide");
  }
});

现在,我有了一个表单,我的用户可以上传他们的简历和照片。当表格有效时,我允许上传他们的照片。它是这样工作的:

$("#send").click(function(e){
   e.preventDefault();
   $.ajax({
      data : $("#bio-form").serialize(),
      url : "/validate.ajax",
      success : function(response) {
        // If AJAX-validator returns "1" then a form is valid  
        if (response == "1"){
            // Now I start to upload photos, like
            // this
            var formData = new FormData(document.getElementById('upload-form'));
            $.ajax({
               processData  : false,
               contentType  : false,
               cache    : false,
               data         : formData,
               success : function(response) {
                  alert(response);
               }
            });
        }
      }
   });
});

问题

一旦ajax上传开始,我希望显示一个$("#ajax-loader")。完成后,应根据我在$.ajaxSetup中定义的设置自动关闭。

但是它在文件上传1秒后出现并消失。我知道ajax请求没有完成,因为我在1-2分钟后收到了成功的消息(照片上传)。

我尝试更改async: false,它开始按预期工作===上传文件到服务器时出现一个模式,完成后消失:

data        : formData,
async       : false,
processData : false,

问题

async : true设置为其默认模式(true)时,是否也可以这样做?我不希望浏览器在上传过程中被冻结!

正如您所发现的,Ajax是一种异步技术,这意味着它按照自己的时间表运行

使Ajax同步会导致各种问题(使用async:false实际上会导致浏览器在执行请求时冻结)

我要提到的几个问题你可能想解决:


为什么嵌套Ajax

在我看来,在当前的网络状态下嵌套Ajax请求是一种糟糕的做法。这通常意味着你的系统出了问题。并发请求很好,但我会避免像瘟疫那样嵌套


Ajax回调

如果您可以将Ajax请求简化为一个实体,我会考虑使用Ajax回调来创建您想要的结果

Ajax回调通过将Ajax作为函数的一部分来工作;错误回调由父函数的几个不同部分处理。这里有一个例子:

 function create_modal(o){
        fetch_modal(o.ajax, function(data){
           //do success stuff here
        }, function(data){
           //do error stuff here
        });
 }
 function fetch_modal(link, success, error) {
     $.ajax({
        url: link,
        success: function(data) { success(data); },
        error: function(data)   { error(data); }
     });
 } 

问题出在ajaxSetup上。您必须按照启用/禁用方法上传照片。让我澄清一下我的理解。您希望向加载程序显示,以告知用户他/她必须等待验证过程完成。一旦验证成功,您就开始上传文件。上传文件时,您希望允许用户与页面进行交互。

要做到这一点,你必须做如下,

function ajaxSetup(mode) {
    var options = {};
    if (mode === "on") {
        options = {
            beforeSend : function() {
                $("#ajax-loader").dialog({
                    modal : true
                });
            },
            complete : function() {
                $("#ajax-loader").dialog("hide");
            }
        };
    } else {
        options = {
            beforeSend : function() {
            },
            complete : function() {
            }
        };
    }
    $.ajaxSetup(options);
}

并按照以下方式提出ajax请求,

ajaxSetup("on");
$("#send").click(function(e) {
    e.preventDefault();
    $.ajax({
        data : $("#bio-form").serialize(),
        url : "/validate.ajax",
        success : function(response) {
            // If AJAX-validator returns "1" then a form is valid
            if (response == "1") {
                // Now I start to upload photos, like
                // this
                var formData = new FormData(document.getElementById('upload-form'));
                ajaxSetup("off"); //Here second-time seem-less displaying of loader will be avoided.
                $.ajax({
                    processData : false,
                    contentType : false,
                    cache : false,
                    data : formData,
                    success : function(response) {
                        alert(response);
                    }
                });
                ajaxSetup("on");
            }
        }
    });
});

注意:我没有测试代码。如果有语法或打字错误,请确认。