从嵌套JSON创建的JavaScript数组返回0表示长度

从嵌套JSON创建的JavaScript数组返回0表示长度,javascript,Javascript,我对JavaScript还是很陌生,但我的程序的基本前提是进行API调用,然后将数据转换成表。我已经测试了buildHtmlTable函数,它可以很好地使用我预先填充了静态数据(不是来自API)的示例数组 在buildHtmlTable函数中console.log(myList.length)返回0。这很可能是问题的根源,因为如果长度为0,那么for(var i=0;i

我对JavaScript还是很陌生,但我的程序的基本前提是进行API调用,然后将数据转换成表。我已经测试了
buildHtmlTable
函数,它可以很好地使用我预先填充了静态数据(不是来自API)的示例数组

buildHtmlTable
函数中
console.log(myList.length)
返回0。这很可能是问题的根源,因为如果长度为0,那么for(var i=0;i根本不会运行

我还尝试使用
.push
将数据添加到表中,但似乎得到了相同的错误

下面是我的代码的样子:

<body onLoad="buildHtmlTable('#excelDataTable')">
  <table id="excelDataTable" border="1">
  </table>
</body>

<script>

  var myList = [];


  function getAPIData() {
    // Create a request variable and assign a new XMLHttpRequest object to it.
    var request = new XMLHttpRequest()


    // Open a new connection, using the GET request on the URL endpoint
    request.open('GET', '/api/table=1/records/', true)
    request.onload = function () {
      // Begin accessing JSON data here
      var data = JSON.parse(this.response)

      n = 0

      if (request.status >= 200 && request.status < 400) {
        data.forEach(record => {
          myList[n] = (record.data);
          n++;
          //console.log(record.data.name)
        })
      } else {
        console.log('error')
      }
    }

    request.send()
    console.log('fin')
  }



  // Builds the HTML Table out of myList.
  function buildHtmlTable(selector) {
    getAPIData()
    console.log(myList.length)

    console.log(1)

    var columns = addAllColumnHeaders(myList, selector);

    console.log(1.1)
    console.log(myList.length)

    for (var i = 0; i < myList.length; i++) {
      console.log(1.2)

      var row$ = $('<tr/>');
      console.log(1.3)

      for (var colIndex = 0; colIndex < columns.length; colIndex++) {
        var cellValue = myList[i][columns[colIndex]];
        if (cellValue == null) cellValue = "";
        row$.append($('<td/>').html(cellValue));
      }
      $(selector).append(row$);
    }

    console.log(2)

  }

  // Adds a header row to the table and returns the set of columns.
  // Need to do union of keys from all records as some records may not contain
  // all records.
  function addAllColumnHeaders(myList, selector) {
    var columnSet = [];
    var headerTr$ = $('<tr/>');

    for (var i = 0; i < myList.length; i++) {
      var rowHash = myList[i];
      for (var key in rowHash) {
        if ($.inArray(key, columnSet) == -1) {
          columnSet.push(key);
          headerTr$.append($('<th/>').html(key));
        }
      }
    }
    $(selector).append(headerTr$);

    return columnSet;
  }
</script>
[
    {
        "id": 1,
        "data": {
            "name": "John Doe",
            "id": "5d7861f38319f297df433ae1"
        }
    },
    {
        "id": 2,
        "data": {
            "name": "John deer",
            "id": "5d7861f38319f297df433ae1"
        }
    },
    {
        "id": 3,
        "data": {
            "name": "Jane Doe",
            "id": "5d79126f48ca13121d673300"
        }
    }
]
知道我哪里出了问题吗?谢谢

编辑:下面是我使用fetch实现的内容。但是,我仍然得到一个长度为0的数组

  async function getAPIData() {
    const response = await fetch('/api/table=1/records/')
    const myJson = await response.json();
    myJson.forEach(record => {
      myList.push(record.data);
    })
  }

XMLHttpRequests是异步的,这意味着您的其余代码在运行之前不会等待它们完成。当您调用
getAPIData()
时,它开始发出请求,但在请求完成之前(因此在填充列表之前),它会转到
buildHtmlTable
的下一行。您应该做的是在
buildHtmlTable
函数外调用
getAPIData
函数,然后在XHR请求的onload回调中调用
buildHtmlTable
。这将确保在运行HTML building函数时加载和填充数据


您还可以切换到使用
fetch
而不是
XMLHttpRequest
;因为
fetch
返回承诺,所以您可以使用ES6
async/await
语法,在buildHtmlTable函数中的代码继续运行之前,只等待API响应r、 因此,如果您不习惯,我会说坚持我的第一个建议。

谢谢您的回复。我能够使用fetch快速构建函数,但仍然面临相同的问题。我已经继续并更新了我的问题以反映新函数。介意看一看吗?谢谢这是一个好的开始。现在您需要创建buildHtmlTab调用一个异步函数,并让它等待getAPIData()。