我必须调用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();
});
};
答案 0 :(得分:1)
您应该使用更好的模型来获取多个项目。使用for循环查询多个获取是一个问题,解决方案应该是重构,以便您发出一个返回所需内容的请求。
如果您似乎无法做到这一点,我已经研究了一种在jQuery中完成您想做的事情的方法。
$.when(
$.get(path, callback), $.get(path, callback), $.get(path, callback)
.then({
//This is called after all requests are done
});
您可以创建所有请求的数组,例如[$ .get(path,callback),request2,request 3等...],然后使用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/
答案 1 :(得分:0)
我认为问题在于您在执行$.wait
之后立即调用getSuites()
。
$.wait
'看到'ajaxCalls
数组为空(因为getSuites()
尚未完成)并执行doneCallback()
。
尝试在$.wait
函数内部调用suitesJSON.done
,这样将在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();
});
});
};