[英]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.