使用 jQuery Deferred 与包含 $.each 的多个 ajax
Using jQuery Deferred with multiple ajax containing $.each
我正在尝试为以下场景创建一个 javascript 对象
一项调查采访了多人,了解他们在几餐中食用的食物。对象需要嵌套如下:-
case={}
case[x].Interview={}
case[x].Interview[y].meals={}
case[x].Interview[y].meals[z].Food=[]
我正在通过以下代码实现这一点
var $caseoffset=0
loadcases()
function loadcases() {
$.ajax({
url: "functions.php",data: {offset: $caseoffset,method: "getCase"},method: "post",dataType: 'json',
success: function(result) {
cases = result;
loadinterview(cases[$caseoffset].fldCaseID)
}
})
}
function loadinterview($CaseID) {
$.ajax({
url: "functions.php",
data: {method: "getinterview",caseid: $CaseID}, method: "post",dataType: 'json',
success: function(result) {
thiscase=cases[$caseoffset]
thiscase.interviewcount=result.length
thiscase.interviews={}
$.each(result,function(key,val){
thiscase.interviews[val.fldInterviewID]=val
loadmeals(val.fldInterviewID)
})
}
})
}
function loadmeals($InterviewID) {
$.ajax({
url: "functions.php",
data: {method: "getmeal",InterviewID: $InterviewID},method: "post",dataType: 'json',
success: function(result) {
thiscase.interviews[parseInt($InterviewID)].mealcount = result.length
thiscase.interviews[parseInt($InterviewID)].meals={}
$.each(result, function(key, val) {
thiscase.interviews[parseInt($InterviewID)].meals[parseInt(val.fldMealHistoryID)] = val
getfoodinmeal($InterviewID, val.fldMealHistoryID)
})
}
})
}
function getfoodinmeal($interviewid, $mealid) {
$.ajax({
url: "functions.php",data: {method: "getfoodinmeal",mealid: $mealid},
method: "post",
dataType: 'json',
success: function(result){
foodinmeal = [];
$.each(result, function(key, val) {
foodinmeal.push(val.fldFoodID)
})
thiscase.interviews[$interviewid].meals[$mealid].food = foodinmeal
}
})
}
问题是我想在每个面试官消耗的所有食物都被编译后进行一些计算。我如何创建延迟语句来解决这个问题。
自 jQuery 1.5 $.ajax()
returns jqXHR
实现 Promise 接口。
这意味着您可以将它与 Promise.all()
( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all )
结合使用
像这样的东西应该可以工作:
Promise.all([
$.ajax({
url: "a.php"
}),
$.ajax({
url: "b.php"
}),
$.ajax({
url: "c.php"
}),
]).then(function() {
// the 3 $ajax() call are finished
})
对中间步骤中的 return 值使用承诺,并使用 Promise.all
组合它们:
function loadcase(offset) {
return $.ajax({
url: "functions.php",
data: {method: "getCase", offset: offset},
method: "post", dataType: 'json',
}).then(function(cases) {
return loadinterview(cases[$caseoffset]);
})
}
function loadinterview(thiscase) {
$.ajax({
url: "functions.php",
data: {method: "getinterview", caseid: thiscase.fldCaseID},
method: "post", dataType: 'json'
}).then(function(result) {
thiscase.interviewcount=result.length
thiscase.interviews={}
var promises = $.map(result,function(key,val){
thiscase.interviews[val.fldInterviewID]=val
return loadmeals(val);
})
return Promise.all(promises).then(function() {
return thiscase;
});
});
}
function loadmeals(thisinterview) {
$.ajax({
url: "functions.php",
data: {method: "getmeal", InterviewID: thisinterview.fldInterviewID},
method: "post", dataType: 'json'
}).then(function(result) {
thisinterview.mealcount = result.length
thisinterview.meals={}
var promises = $.map(result, function(key, val) {
thisinterview.meals[val.fldMealHistoryID] = val
return getfoodinmeal(val);
})
return Promise.all(promises).then(function() {
return thisinterview;
});
})
}
function getfoodinmeal(thismeal) {
$.ajax({
url: "functions.php",
data: {method: "getfoodinmeal", mealid: thismeal.fldMealHistoryID},
method: "post", dataType: 'json',
}).then(function(result) {
thismeal.food = $.map(result, function(key, val) {
return val.fldFoodID;
})l
return thismeal;
})
}
loadcase(0).then(function(case) {
// everything is loaded
console.log(case);
})
这里的两个答案都很好,但问题是 Promise
接口仅在 ES6 中可用。有两种可能的情况。
- 使用 polyfill -> https://www.npmjs.com/package/promise-polyfill
- 使用
jQuery.when()
。假设您创建了一个数组,其中包含对 getfoodinmeal
的所有请求承诺。然后你需要等待所有这些,所以使用这种形式$.when.apply($.when, promises).then(/* all food is now loaded*/);
。我用了两次,效果很好。我更喜欢这种方式,因为我不需要加载额外的代码。
以上所有答案都很好,可以解决您的问题。但是调用多个 ajax 调用会损害网站的性能。如果您不使用第三方 API 并且 API 在您的控制之下,那么您应该更改 API 并使其更加灵活。 API 应该设计成这样,你可以用参数数量查询它,它会 return 在单个请求中得到结果。例如。在上述情况下,您可以在单个请求中传递所有 ID,并获取所有 ID 的数据。或者在最好的情况下,您只需询问案例,它将 return 您需要的所有信息(面试、膳食和食物)。 API 负责以您需要的形式查询数据。
我正在尝试为以下场景创建一个 javascript 对象
一项调查采访了多人,了解他们在几餐中食用的食物。对象需要嵌套如下:-
case={}
case[x].Interview={}
case[x].Interview[y].meals={}
case[x].Interview[y].meals[z].Food=[]
我正在通过以下代码实现这一点
var $caseoffset=0
loadcases()
function loadcases() {
$.ajax({
url: "functions.php",data: {offset: $caseoffset,method: "getCase"},method: "post",dataType: 'json',
success: function(result) {
cases = result;
loadinterview(cases[$caseoffset].fldCaseID)
}
})
}
function loadinterview($CaseID) {
$.ajax({
url: "functions.php",
data: {method: "getinterview",caseid: $CaseID}, method: "post",dataType: 'json',
success: function(result) {
thiscase=cases[$caseoffset]
thiscase.interviewcount=result.length
thiscase.interviews={}
$.each(result,function(key,val){
thiscase.interviews[val.fldInterviewID]=val
loadmeals(val.fldInterviewID)
})
}
})
}
function loadmeals($InterviewID) {
$.ajax({
url: "functions.php",
data: {method: "getmeal",InterviewID: $InterviewID},method: "post",dataType: 'json',
success: function(result) {
thiscase.interviews[parseInt($InterviewID)].mealcount = result.length
thiscase.interviews[parseInt($InterviewID)].meals={}
$.each(result, function(key, val) {
thiscase.interviews[parseInt($InterviewID)].meals[parseInt(val.fldMealHistoryID)] = val
getfoodinmeal($InterviewID, val.fldMealHistoryID)
})
}
})
}
function getfoodinmeal($interviewid, $mealid) {
$.ajax({
url: "functions.php",data: {method: "getfoodinmeal",mealid: $mealid},
method: "post",
dataType: 'json',
success: function(result){
foodinmeal = [];
$.each(result, function(key, val) {
foodinmeal.push(val.fldFoodID)
})
thiscase.interviews[$interviewid].meals[$mealid].food = foodinmeal
}
})
}
问题是我想在每个面试官消耗的所有食物都被编译后进行一些计算。我如何创建延迟语句来解决这个问题。
自 jQuery 1.5 $.ajax()
returns jqXHR
实现 Promise 接口。
这意味着您可以将它与 Promise.all()
( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all )
像这样的东西应该可以工作:
Promise.all([
$.ajax({
url: "a.php"
}),
$.ajax({
url: "b.php"
}),
$.ajax({
url: "c.php"
}),
]).then(function() {
// the 3 $ajax() call are finished
})
对中间步骤中的 return 值使用承诺,并使用 Promise.all
组合它们:
function loadcase(offset) {
return $.ajax({
url: "functions.php",
data: {method: "getCase", offset: offset},
method: "post", dataType: 'json',
}).then(function(cases) {
return loadinterview(cases[$caseoffset]);
})
}
function loadinterview(thiscase) {
$.ajax({
url: "functions.php",
data: {method: "getinterview", caseid: thiscase.fldCaseID},
method: "post", dataType: 'json'
}).then(function(result) {
thiscase.interviewcount=result.length
thiscase.interviews={}
var promises = $.map(result,function(key,val){
thiscase.interviews[val.fldInterviewID]=val
return loadmeals(val);
})
return Promise.all(promises).then(function() {
return thiscase;
});
});
}
function loadmeals(thisinterview) {
$.ajax({
url: "functions.php",
data: {method: "getmeal", InterviewID: thisinterview.fldInterviewID},
method: "post", dataType: 'json'
}).then(function(result) {
thisinterview.mealcount = result.length
thisinterview.meals={}
var promises = $.map(result, function(key, val) {
thisinterview.meals[val.fldMealHistoryID] = val
return getfoodinmeal(val);
})
return Promise.all(promises).then(function() {
return thisinterview;
});
})
}
function getfoodinmeal(thismeal) {
$.ajax({
url: "functions.php",
data: {method: "getfoodinmeal", mealid: thismeal.fldMealHistoryID},
method: "post", dataType: 'json',
}).then(function(result) {
thismeal.food = $.map(result, function(key, val) {
return val.fldFoodID;
})l
return thismeal;
})
}
loadcase(0).then(function(case) {
// everything is loaded
console.log(case);
})
这里的两个答案都很好,但问题是 Promise
接口仅在 ES6 中可用。有两种可能的情况。
- 使用 polyfill -> https://www.npmjs.com/package/promise-polyfill
- 使用
jQuery.when()
。假设您创建了一个数组,其中包含对getfoodinmeal
的所有请求承诺。然后你需要等待所有这些,所以使用这种形式$.when.apply($.when, promises).then(/* all food is now loaded*/);
。我用了两次,效果很好。我更喜欢这种方式,因为我不需要加载额外的代码。
以上所有答案都很好,可以解决您的问题。但是调用多个 ajax 调用会损害网站的性能。如果您不使用第三方 API 并且 API 在您的控制之下,那么您应该更改 API 并使其更加灵活。 API 应该设计成这样,你可以用参数数量查询它,它会 return 在单个请求中得到结果。例如。在上述情况下,您可以在单个请求中传递所有 ID,并获取所有 ID 的数据。或者在最好的情况下,您只需询问案例,它将 return 您需要的所有信息(面试、膳食和食物)。 API 负责以您需要的形式查询数据。