javascript - jQuery : How can I call $. ajax 在嵌套 ajax 调用场景中满足特定条件时?

标签 javascript jquery ajax html

用代码更新了问题

我遇到一种情况,我依次调用两个嵌套的 ajax 调用。第一个 ajax 调用提交一个不带附件的表单。第一个 ajax 调用的结果将创建一个 requestId,使用第二个 ajax 调用时,我必须将多个附件附加到创建的 requestId

以下代码的结果是,第一次和第二次 ajax 调用都被调用 N 次附件。例如:- 如果有 3 个附件,则 createRequestId ajax 调用(第一个 ajax 调用)调用 3 次,从而创建 3 个 requestId。我的问题是,createRequestId ajax 调用只需调用一次(第一次),并且在循环的其余部分中,只应调用第二次 ajax 调用。我怎样才能在下面的代码中实现这一点?

Current situation

RequestId 1,Attachment 1
RequestId 2,Attachment 2
RequestId 3, Attachment 3

Expected output

RequestId 1, Attachment 1, Attachment 2, Attachment 3

//loop through number of attachments in the form
$("#myDiv").find("input[type=file]").each(function(index,obj) {
   var fObj = $(obj),
       fName = fObj.attr("name"),
       fileDetail = document.getElementById(fName).files[0];
       //FileSize Validation
       if(fileDetail !=undefined && fileDetail !=null)
        {
          if(fileDetail.size > 5*Math.pow(1024,2))

           { 
              alert("Please upload the attachment which is less than 5 MB");
              return false
           }
         }

       $.ajax({    //First Ajax Call
          url: 'http://..../createRequestId'
          type:'POST'
          data: stringify(formData)
          success: function(resObj){
             $("#showResponseArea span").removeClass("hide");
             $("#showResponseArea span").removeClass("alert-success");
             var requestId = resObj.requestId;    

              if(requestId>1 && fileDetail !=undefined && fileDetail !=null) {
                 $.ajax({       //Second Ajax Call
                     url: 'http://..../doAttach?fileName=' + fileDetail.name + 
                           '&requestId=' +requestId,    
                     type:'POST',
                     data: fileDetail,
                     success: function(resObj){
                               alert("Attachment Successful");

                      }
                      error : function(data) {
                        alert("Failed with the attachment");
                       }
                  });                
                } 
               },
              error: funciton(resObj) {
                    alert("Some Error Occured");
              }
           });
        });

最佳答案

我知道这并不能真正完全回答您的问题,但如果您不介意我提供一些建设性的代码审查。当代码全部被扔进一个包含很多行的大函数中时,很难真正管理和调试代码,特别是当您嵌套异步调用时(您正接近嵌套回调 hell )。这样的代码很难维护并且令人困惑,这是有原因的。

让我们合并一些Clean Code将它们分解为更小的命名函数的概念,以提高可读性、可测试性和可维护性(并且能够更好地调试):

首先,您不需要所有这些 !== 和未定义的检查。只要这样做:

if (fileDetail)

if(requestId>1 && fileDetail)

检查 fileDetail 上是否为 null 和未定义。

然后我开始将这两个 ajax 调用分解为几个命名函数,并让函数名称及其签名暗示它们实际执行的操作,然后您可以删除代码中不必要的注释以及分解它们后,通常你会发现可以删除的重复代码(例如多余的post()代码),并且你会发现你提取出来的代码现在可以进行测试。

我倾向于在我的代码中寻找可以首先尝试提取的行为。因此,这些​if​ 语句中的每一个都可以轻松地提取到它们自己的命名函数中,因为代码中的任何 if 语句通常都会翻译为“行为”。如您所知,行为可以隔离到它们自己的模块、方法、类等中......

例如,您的第一个 if 语句可以提取到它自己的函数中。请注意,我在这里也删除了额外的 if 语句:

function validateFileSize(fileDetail)
    if(!fileDetail && !fileDetail.size > 5*Math.pow(1024,2)){
      alert("Please upload the attachment which is less than 5 MB");
      return false
    };
};

因此,您可以通过以下方式开始将事情变得更清晰(这可能会得到更多改进,但这至少是一个开始):

$("#myDiv").find("input[type=file]").each(function(index,obj) {
    var fObj = $(obj),
        fileName = fObj.attr("name"),
        file = document.getElementById(fileName).files[0];

    validateFileSize(file);
    post(file, 'http://..../createRequestId');
});

// guess what, if I wanted, I could slap on a test for this behavior now that it's been extracted out to it's own function
function validateFileSize(file){
    if(!file && !file.size > 5*Math.pow(1024,2)){
        alert("Please upload the attachment which is less than 5 MB");
        return false
    };
};

function post(url, data){
    $.ajax({
        url: url,
        type:'POST',
        data: stringify(data),
        success: function(res){
            showSuccess();

            var id = res.requestId;

            if(id > 1 && file){
                var url = 'http://..../doAttach?fileName=' + file.name + '&requestId=' + id;
                postData(file, url);
            }
        },
        error: function(err) {
            alert("Some Error Occurred: " + err);
        }
});

// I didn't finish this, and am repeating some stuff here so you could really refactor and create just one post() method and rid some of this duplication
function postData(file, url){
    $.ajax({
        url: url,
        type:'POST',
        data: file,
        success: function(res){
            alert("Attachment Successful");
        },
        error : function(data) {
            alert("Failed with the attachment");
        }
    });
};

// this is behavior specific to your form, break stuff like this out into their own functions...
function showSuccess() {
    $("#showResponseArea span").removeClass("hide");
    $("#showResponseArea span").removeClass("alert-success");
};

我将其留在这里,接下来您可以删除一些重复的 $ajax() 代码并创建一个通用的 post() util 方法,该方法可以重用,并将任何其他行为从这些方法移出并移入它们的方法中。自己的,以便您可以重复使用一些 jQuery ajax 调用语法。

然后最终尝试合并 promise 或 promise +生成器链接这些异步调用,这可能会使维护和调试更容易。 :)。

关于javascript - jQuery : How can I call $. ajax 在嵌套 ajax 调用场景中满足特定条件时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38195419/

相关文章:

javascript - 如何在 FeathersJS 服务扩展中使用 app.service ('myService' )?

javascript - 在 PHP 中构建 JSON 并在 <script> 中回显时转义字符

javascript - 对象不支持属性或方法 'menu' JQUERY

jQuery IE 文本动画给出奇怪的效果

javascript - 在 jquery 发布后更新 div 显示而不重新加载 mvc3 中的页面

javascript - Ajax、JavaScript、PhP 从 td 获取值并将其保存在 SQL 数据库中

javascript - amp-story 已经注册。 amp-story 的脚本标记可能在页面中包含两次

javascript - 为什么我的 charAt 函数不能在我的 javascript 上运行?

javascript - 将事件绑定(bind)到父级时如何检测输入类型

mysql - Kohana 3.2 选择问题