运行javascript循环,异步结果

时间:2020-07-05 16:08:57

标签: javascript ajax loops asynchronous

我有50个JSON文件。 (1.json,2.json ... 50.json)。 每个的结构是:

{
  "book": "Księga Wyjścia",
  "chapter": 1,
  "type": "verses",
  "verses": [
    {
      "text": "Oto imiona synów Izraela, którzy razem z Jakubem przybyli do Egiptu. Każdy zaś przyszedł ze swoją rodziną:",
      "verse": "1"
    },
    {
      "text": "Ruben, Symeon, Lewi, Juda;",
      "verse": "2"
    },
    {
      "text": "Issachar, Zabulon i Beniamin;",
      "verse": "3"
    },
    {
      "text": "Dan, Neftali, Gad i Aser.",
      "verse": "4"
    },
    {
      "text": "Było zaś wszystkich potomków Jakuba siedemdziesiąt osób, Józef zaś już był w Egipcie.",
      "verse": "5"
    }
  ]
}

每个文件中都有更多的经文,每个文件的大小可以完全不同(因此它们不会立即加载)。 我加载“章节”节点。每次刷新文件时,都会得到不同的顺序,即。 (仅来自最近一次刷新的最后几个数字):28,35,32,36,37,29,30,31,38,33,49,50,39,40,41,42,43,44,45,46, 47,48

<script>
  for (i = 1; i <= 50; i++) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        var input = JSON.parse(this.responseText);
        console.log(input.chapter);

      }
    };
    xmlhttp.open("GET", (i + ".json"), true);
    xmlhttp.send();
  }
</script>

我认为是因为它加载异步。我可以强制脚本同步加载吗?

2 个答案:

答案 0 :(得分:3)

使用fetch API和promises的力量:

let promises = [];
for (let i = 1; i <= 50; i++) {
    promises.push(fetch(i + ".json").then(resp => resp.json());
}
Promise.all(promises).then(function(inputs) {
    inputs.forEach(input => console.log(input.chapter));
});

即使承诺可以以不同的顺序解决,Promise.all也会解析为一系列响应,这些响应将维持承诺的原始顺序。

注意:请确保使用ivarlet定义变量(如const

答案 1 :(得分:0)

您应该保持请求异步 ,因为这不仅可以节省加载时间,而且如果任何请求的响应时间太长,则不会加载其他任何章节直到该请求解决。

首先,我建议您创建一个responses数组,并在回调中将JSON响应推送到该数组,并检查到目前为止收到的responses的数量,响应数为50,表示所有章节均已加载。此时,基于sort()的{​​{1}} responses 完成后,您就可以继续chapter

注意::您需要定义doSomething()函数,该函数将所有章节按顺序输入并对其进行处理。

doSomething()

就像@MoshFeu和@trincot建议的那样,使用<script> var responses = []; for (i = 1; i <= 50; i++) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var input = JSON.parse(this.responseText); responses.push(input); if (responses.length === 50) { responses = responses.sort(function(a, b) { return a.chapter < b.chapter; }); doSomething(responses); } } }; xmlhttp.open("GET", (i + ".json"), true); xmlhttp.send(); } </script> 会更容易,如果您将注意力放在fetch上,那么Promise和{{ 1}}用于所有异步工作的语法。