【发布时间】:2016-07-13 21:23:49
【问题描述】:
我需要从服务器加载一个 JSON 文件,稍后我将使用它来填充网站上的内容。使用XMLHttpRequest 加载 JSON 文件应该是异步的,并且可以尽快发生。然而,填充内容需要加载 DOM。
现在,我调用xhr.open('GET', 'records.json', false) 使请求同步。当加载和解析 JSON 所花费的时间比浏览器加载 DOM 所花费的时间更多时,这是必要的。当这种情况发生时(即连接速度较慢),DOM 将被加载,DOMContentLoaded 事件监听器中的代码将在 listData 上执行,undefined 仍然是 undefined。不好。
如何使用异步XMLHttpRequest 并同时在DOMContentLoaded 上执行我的代码?我想在 listData 完全加载(即 JSON.parse() 完成)并且 DOM 可用后立即执行我的代码。当这两个条件都满足时,我就可以走了。
function thisFunctionIsCalledFromTheHtml() {
// Get the JSON data by using a XML http request
var listData;
var xhr = new XMLHttpRequest();
// The request needs to be synchronous for now because on slow connections the DOM is ready
// before it fetches everything from the json file
xhr.open('GET', 'records.json', false);
xhr.addEventListener("load", function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
listData = JSON.parse(xhr.responseText);
} else {
console.error('Error: ' + xhr.status + ' ' + xhr.statusText);
}
}
});
xhr.addEventListener("error", function() {
console.error('Error: ' + xhr.status + ' ' + xhr.statusText);
});
xhr.send(null);
document.addEventListener("DOMContentLoaded", function() {
var placeholderKeys = [];
for (var key in listData) {
var value = listData[key];
placeholderKeys = placeholderKeys.concat(value.title, value.abbr, value.keywords);
}
var filterInput = document.getElementById('input-id');
filterInput.placeholder = placeholderKeys[
Math.floor(Math.random() * placeholderKeys.length)
];
});
}
【问题讨论】:
-
如果您确保从放置在元素之后的脚本标记调用此函数,则不需要
DOMContentLoaded -
@charlietfl 但我不想等到加载 DOM 之后再加载 JSON。这应该尽快发生。
-
替代方案是返回一个承诺并将承诺回调放入
DOMContentLoaded。
标签: javascript json asynchronous xmlhttprequest