嵌套的getJSON调用

时间:2018-05-30 17:59:28

标签: javascript jquery html json

在我的项目中,我要求进行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"}
]

请建议正确的方法是什么?

谢谢

1 个答案:

答案 0 :(得分:1)

问题是因为在所有AJAX请求完成并且它们的回调运行之前,外部循环已经完成。因此,projectKeyprojectNamemyURL变量都包含最后一次迭代的值

要解决此问题,您可以在内部调用周围使用闭包来维护传入的变量的范围:

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...
});