用代码更新了问题
我遇到一种情况,我依次调用两个嵌套的 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/