This question already has answers here:
How do I return the response from an asynchronous call?
(38个答案)
在8个月前关闭。
我对JavaScript还是很陌生,但是程序的基本前提是进行API调用,然后将数据转换为表。我已经测试了
在
我也尝试过使用
这是我的代码:
至于请求的数据,这就是返回的JSON的样子:
有什么想法我在这里错了吗?谢谢。
编辑:这是我使用fetch的实现。但是,我仍然得到长度为0的数组。
(38个答案)
在8个月前关闭。
我对JavaScript还是很陌生,但是程序的基本前提是进行API调用,然后将数据转换为表。我已经测试了
buildHtmlTable
函数,并且该函数与预先填充了静态数据(不是来自API)的示例数组可以正常工作。在
buildHtmlTable
函数中,console.log(myList.length)
返回0。这很可能是问题出处,因为如果length为0,则for (var i = 0; i < myList.length; 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>
至于请求的数据,这就是返回的JSON的样子:
[
{
"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);
})
}
最佳答案
XMLHttpRequest是异步的,这意味着您的其余代码不会在它们运行之前等待它们完成。当您调用getAPIData()
时,它开始发出请求,但是在请求完成之前(因此在填充列表之前),它会转到buildHtmlTable
的下一行。您应该做的是在getAPIData
函数外部调用buildHtmlTable
函数,然后在XHR请求的onload回调中调用buildHtmlTable
。这将确保在运行HTML构建功能时加载和填充数据。
您也可以切换为使用fetch
代替XMLHttpRequest
;由于fetch
返回承诺,因此您可以使用ES6 async / await
语法在buildHtmlTable函数内部的代码继续之前等待API响应。但这是思考AJAX和异步行为的新方法,因此,如果您不习惯,我会说坚持我的第一个建议。
07-24 14:58