在我的项目中,我要求进行rest API
调用并获取JSON
数组作为回应。
每个数组元素都包含一个' key' (项目键)项。 响应示例为here。
现在我想循环遍历这个数组,获取项目密钥,然后再进行一次REST调用以获取每个项目的详细信息。
我使用下面的代码执行此操作,但最终输出未达到预期效果。
var myOutput = [];
$.when (
$.getJSON(projectListURL, function (data) {
var compArr = data.components;
for (i=0 ; i<compArr.length ; i++) {
var projectKey = compArr[i].key;
var projectName = compArr[i].name;
var myURL = "http://myserver.com/projectdetails?projectkey=" + projectKey;
$.getJSON(myURL, function (data) {
}).then (function (data){
console.log("myURL:" + myURL);
console.log("name:" + projectName);
var item = {};
item["name"] = projectName;
item["status"] = data.projectStatus.status;
console.log(item);
myOutput.push(item);
});
}
})
).done (function () {
console.log(myOutput);
});
我希望myOutput类似于:
[
{name: "BaseProj", status: "OK"},
{name: "Sudoku Project", status: "ERROR"},
{name: "My Project", status: "WARN"}
]
但我得到了:
[
{name: "My Project", status: "OK"},
{name: "My Project", status: "ERROR"},
{name: "My Project", status: "WARN"}
]
请建议正确的方法是什么?
谢谢
答案 0 :(得分:1)
问题是因为在所有AJAX请求完成并且它们的回调运行之前,外部循环已经完成。因此,projectKey
,projectName
和myURL
变量都包含最后一次迭代的值。
要解决此问题,您可以在内部调用周围使用闭包来维护传入的变量的范围:
var myOutput = [];
$.when(
$.getJSON(projectListURL, function(data) {
var compArr = data.components;
for (i = 0; i < compArr.length; i++) {
var projectKey = compArr[i].key;
var projectName = compArr[i].name;
var myURL = "http://myserver.com/projectdetails?projectkey=" + projectKey;
(function(url, name) {
$.getJSON(url, function(data) {
}).then(function(data) {
console.log("myURL:" + url);
console.log("name:" + name);
var item = {
name: name,
status: data.projectStatus.status
};
console.log(item);
myOutput.push(item);
});
})(myURL, projectName);
}
})
).done(function() {
console.log(myOutput);
});
或者,您可以避免使用闭包并使用let
关键字而不是var
来定义变量,但请注意,这不适用于&lt; IE11。
最后请注意,在任何一种情况下,您都可以删除$.getJSON
调用的回调处理函数,因为您没有使用它,例如:
$.getJSON(myURL).then(function(data) {
// code...
});