簡體   English   中英

jQuery:在嵌套的ajax調用場景中滿足特定條件時,如何調用$ .ajax?

[英]jQuery : How can I call $.ajax when a particular condition is met in the nested ajax calls scenario?

用代碼更新問題

我遇到的情況是我一個接一個地調用兩個嵌套的ajax調用。 第一個ajax調用提交不帶附件的表單。 第一個ajax調用的結果將創建一個requestId ,使用第二個ajax調用我必須將多個附件附加到創建的requestId

以下代碼的結果是,第一次和第二次ajax調用均被調用N次。 例如:-如果有3個附件,則createRequestId ajax調用(第一個ajax調用)被調用3次,這將創建3個requestId 我的問題是,只需一次(第一次)調用createRequestId ajax調用,在循環的其余部分中,僅應調用第二個ajax調用。 如何在下面的代碼中實現呢?

現在的情況

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

預期產量

RequestId 1,附件1,附件2,附件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");
              }
           });
        });

我知道這並不能完全回答您的問題,但是如果您不介意我提供一些建設性的代碼審查,則可以。 將代碼全部扔進一個包含很多行的大函數中時,很難真正地對其進行管理和調試,尤其是在嵌套異步調用的情況下(接近嵌套的回調地獄)。 這樣的代碼有一個原因,很難維護和造成混淆。

讓我們結合一些“ 清潔代碼”概念,這些概念將這些概念分解為更小的命名函數,以提高可讀性,可測試性和可維護性(並能夠更好地進行調試):

首先,您不需要所有這些!==和未定義的檢查。 做就是了:

if (fileDetail)

if(requestId>1 && fileDetail)

檢查fileDetail上是否為null和undefined。

然后,我將把這兩個ajax調用分解為幾個命名函數,然后讓函數名及其簽名暗示它們的實際作用,然后您就可以刪除代碼中不必要的注釋,以及一旦分解它們,通常可以找到可以刪除的重復代碼(例如冗余的post()代碼),您會發現提取出的代碼現在可以進行測試。

我傾向於尋找在我的代碼的行為 ,我可以嘗試先提取出來。 因此,如果這些中的每一個語句可以很容易地抽出自己命名的功能,因為如果任何在代碼中的語句通常被轉化為“行為”。 如您所知,行為可以隔離到各自的模塊,方法,類中,無論...

因此,例如,首先可以將您擁有的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 +生成器鏈接那些異步調用,這可能會使維護和調試更加容易。 :)。

我認為您的循環完全在錯誤的位置。 實際上,您正在迭代文件並進行兩次AJAX調用。 編輯 :我現在顯示在第一個AJAX調用之前進行額外驗證的適當位置。 實際的驗證不是問題的一部分,也不包含在其中,但是您可以參考JavaScript文件上傳大小驗證

var fileSizesValid = true;
$("#myDiv").find("input[type=file]").each(function(index, obj) {
  // First loop checks file size, and if any file is > 5MB, set fileSizesValid to false
});

if (fileSizesValid) {
  $.ajax({ //First Ajax Call
    url: 'http://..../createRequestId',
    type: 'POST',
    data: stringify(formData),
    success: function(resObj) {
      var fObj = $(obj),
        fName = fObj.attr("name"),
        fileDetail = document.getElementById(fName).files[0];
      //loop through number of attachments in the form
      $("#myDiv").find("input[type=file]").each(function(index, obj) {

        $("#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: function(resObj) {
      alert("Some Error Occured");
    }
  });
}

另外,請注意將牙套放在何處。 在JavaScript中,花括號應始終位於行尾,而不是開頭。 這不是樣式首選項,因為它是大多數語言,但是由於分號的插入 ,因此是實際的要求。

嘗試以下代碼(只需重新排列代碼,沒有新內容):

//loop through number of attachments in the form
var requestId;
$("#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
       } else if(!requestId || requestId <= 1){
          $.ajax({    //First Ajax Call
          url: 'http://..../createRequestId'
          type:'POST'
          data: stringify(formData)
            success: function(resObj){
                $("#showResponseArea span").removeClass("hide");
                $("#showResponseArea span").removeClass("alert-success");
                requestId = resObj.requestId;  
                    secondAjaxCall(fileDetail);
            },
            error: funciton(resObj) {
                alert("Some Error Occured");
            }
          });
       } else if(requestId>1) {
            secondAjaxCall(fileDetail);        
        }

     }


    });

    function secondAjaxCall(fileDetail) {
        $.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");
               }
          });     
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM