我必须调用Agile Central API来获取缺陷套件的列表,然后迭代该列表并进行嵌套调用以获取每个套件中的缺陷列表,该嵌套调用依赖于外部调用。然后,我必须将数据行附加到一个表中,然后调用doneCallback()来表示数据收集的结束。我遇到的问题是doneCallback()在请求完成之前就被调用了,所以实际上没有任何数据被传递
我已经尝试了这篇文章中的方法:Wait until all jQuery Ajax requests are done?和这篇文章:how to wait until Array is filled (asynchronous)。在控制台中,我可以看到我想要的所有数据都在那里,但没有附加任何内容。我的问题是:在循环中的所有请求完成并推送数据之前,如何确保不调用doneCallback()?下面是我现在的代码:
function getSuites() {
return $.ajax({
url: suitesURL("71101309592") + "&fetch=Name,FormattedID,Defects",
type: "GET",
xhrFields: {
withCredentials: true
},
headers: {
"zsessionid": apiKey
}
});
}
function getDefects(_ref) {
return $.ajax({
url: _ref,
type:"GET",
xhrFields: {
withCredentials: true
},
headers: {
"zsessionid": apiKey
}
});
}
// Download the data
myConnector.getData = function (table, doneCallback) {
console.log("Getting Data...");
var ajaxCalls = [], tableData = [];
var suitesJSON = getSuites();
suitesJSON.done(function(data) {
var suites = data.QueryResult.Results;
for(var i = 0; i < suites.length; i++) {
(function(i) {
var defectsJSON = getDefects(suites[i].Defects._ref + "?fetch=Name,FormattedID,State,Priority,CreationDate,c_RootCause,c_RootCauseCRM");
ajaxCalls.push(defectsJSON);
defectsJSON.done(function(data) {
var defects = data.QueryResult.Results;
for(var j = 0; j < defects.length; j++) {
tableData.push({
"suiteName": suites[i].Name, // This is the name of the suite collected in the outer call
"defectName": defects[j].Name,
"FormattedID": defects[j].FormattedID,
"State": defects[j].State,
"Priority": defects[j].Priority,
"CreationDate": defects[j].CreationDate,
"RootCause": defects[j].c_RootCause,
"RootCauseCRM": defects[j].c_RootCauseCRM
});
}
});
})(i);
}
});
$.when.apply($, ajaxCalls).then(function() {
console.log(tableData);
table.appendRows(tableData);
doneCallback();
});
};发布于 2019-06-01 03:02:21
我认为问题在于您是在getSuites()执行之后立即调用$.wait的。
$.wait“看到”ajaxCalls数组为空(因为getSuites()还没有完成),然后执行doneCallback()。
尝试在suitesJSON.done函数中调用$.wait,这样它将在ajaxCalls数组填充第一个响应后被调用:
myConnector.getData = function (table, doneCallback) {
console.log("Getting Data...");
var ajaxCalls = [], tableData = [];
var suitesJSON = getSuites();
suitesJSON.done(function(data) {
var suites = data.QueryResult.Results;
for(var i = 0; i < suites.length; i++) {
(function(i) {
var defectsJSON = getDefects(suites[i].Defects._ref + "?fetch=Name,FormattedID,State,Priority,CreationDate,c_RootCause,c_RootCauseCRM");
ajaxCalls.push(defectsJSON);
defectsJSON.done(function(data) {
var defects = data.QueryResult.Results;
for(var j = 0; j < defects.length; j++) {
tableData.push({
"suiteName": suites[i].Name, // This is the name of the suite collected in the outer call
"defectName": defects[j].Name,
"FormattedID": defects[j].FormattedID,
"State": defects[j].State,
"Priority": defects[j].Priority,
"CreationDate": defects[j].CreationDate,
"RootCause": defects[j].c_RootCause,
"RootCauseCRM": defects[j].c_RootCauseCRM
});
}
});
})(i);
}
$.when.apply($, ajaxCalls).then(function() {
console.log(tableData);
table.appendRows(tableData);
doneCallback();
});
});
};发布于 2019-06-01 02:42:14
您应该使用更好的模型来获取多个项目。使用for循环查询多个get是问题所在,解决方案应该是重构,以便发出一个请求来返回所需的所有内容。
如果你觉得这不可能,我已经研究了一种在jQuery中做你想做的事情的方法。
$.when(
$.get(path, callback), $.get(path, callback), $.get(path, callback)
.then({
//This is called after all requests are done
});你可以创建一个包含所有请求的数组,比如$.get(路径,回调),request2,Request3,等等……然后使用spread方法将它们作为参数放入其中,例如
var args = [$.get(path, callback), request2, request 3, etc...];
$.when(...args).then(() => {/*call here*/});此链接包含https://css-tricks.com/multiple-simultaneous-ajax-requests-one-callback-jquery/的其余信息
https://stackoverflow.com/questions/56399004
复制相似问题