javascript - 使用来自多个 XMLHttpRequest 的响应更新 DOM
问题描述
我正在构建一个简单的开源 Chromium 扩展,它从多个 url 检索一些数据,然后更新 DOM。我可以找到另一种方法来做到这一点,而不是在回调中添加更新 DOM 的行http1.onreadystatechange
我的XMLHttpRequest
请求经常被卡住,http1.readyState = 3
所以我添加了第三个参数来http1.open("GET");
使请求同步,如下所示:
http1.open("GET", url, false);
但我仍然收到这些错误:
results[1].join is not a function at XMLHttpRequest.http.onreadystatechange
annot read property 'join' of undefined at XMLHttpRequest.http.onreadystatechange
即使他们不会阻止脚本运行,我认为这不是做我想做的事情的正确方法。所以这是我的问题:如何使用来自多个 XMLHttpRequest 请求的响应来更新 DOM?假设我需要在更新 DOM 之前检索和比较所有数据。那么有没有办法在我们检索完所有数据后立即处理所有数据(参见我对最后一行的评论)?
这是我的脚本的相关部分,完整的脚本可在此处获得:
var urls = [
["https://www.cnrtl.fr/morphologie/" + keyword, "vtoolbar", "morf_sound"], //best for plural
["https://www.cnrtl.fr/synonymie/" + keyword, "syno_format"],
]
// for test set keyword to any of this word : hibou, tribal, aller, lancer
var resultdiv = document.getElementById("result")
resultdiv.innerText = "requete en cours";
var results = [];
var errors = [];
urls.forEach((item, index) => {
var http = new XMLHttpRequest();
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
parser = new DOMParser();
var ulr1response = parser.parseFromString(http.responseText, "text/html");
if (index == 0) {
//retrieve the data needed, save then in a list and push this list to the main list result
} else if (index == 1) {
//retrieve the data needed, save then in a list and push this list to the main list result
}
// update the DOM
if (results[1] == "") {
resultdiv.innerHTML = results[0].join(", ") + "</br></br>Pas de synonymes trouvés"
} else {
resultdiv.innerHTML = "<b>" + results[0].join(", ") + "</br></br>Synonymes:</b></br>● " + results[1].join('</br>● ')
}
} else {
errors.push(index);
resultdiv.innerText = "Erreur: " + index + " " + http.readyState + " " + http.status;
}
}
http.open("GET", item[0], false);
http.send(null); // null = no parameters
});
// it would be simplier if I could update the DOM here and not in http.onreadystatechange
解决方案
如果你想在所有请求都成功后执行一些代码,你可以尝试使用Promise.all和Fetch。
let keyword = "beaucoup";
let parser = new DOMParser();
let urls = [
["https://www.cnrtl.fr/morphologie/" + keyword, "vtoolbar", "morf_sound"], //best for plural
["https://www.cnrtl.fr/synonymie/" + keyword, "syno_format"]
];
let fetchPromises = urls.map(
item => fetch(item[0]).then(
response => parser.parseFromString(response.text(), "text/html")
)
);
Promise.all(fetchPromises).then(
results => {
// code in here executes once all fetchPromises have succeeded
// "results" will be an array of parsed response data
console.log(results);
}
).catch(console.error);
推荐阅读
- reactjs - 如何在 ReactHooks 中使用 useRef 使子菜单的每一项都会独立改变背景
- react-native - 在反应本机导航中自定义标题
- gpu - 使用 nvidia gpu 使用 xserver (mobaxterm) 在 wsl2 中运行gazebo7(错误:[gazebo-4] 进程已死亡)
- c++ - 我在使用数组/函数的 C++ 程序时遇到问题
- python - 通过子进程同时传递单引号和双引号的问题?
- sql - 如何在 PostgreSQL 的检查约束中使用强制转换函数
- laravel - laravel 8.x 测试 api 返回错误的状态码
- python-3.x - Ubuntu 20.10 上的 TensorFlow 错误:ImportError: cannot import name 'run' from 'absl.app'
- html - Vue v-html 指令不运行