首页 > 解决方案 > 使用来自多个 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

标签: javascriptxmlhttprequest

解决方案


如果你想在所有请求都成功后执行一些代码,你可以尝试使用Promise.allFetch

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


推荐阅读