【问题标题】:How to use multiple XMLHttpRequest?如何使用多个 XMLHttpRequest?
【发布时间】:2018-03-12 05:29:14
【问题描述】:

我需要从 8 个不同的 URL 获取 8 个 JSON。我将必须更改的查询字符串存储在一个数组中,并使用 for 循环遍历它。这是我的代码:

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];

var request = new XMLHttpRequest();

for (var i = 0; i < index.length; i++) {

    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    request.open("GET", url);
    request.onload = function() {
        var data = JSON.parse(request.responseText);
        console.log(data);
    }
    request.send();
}

到目前为止,我只想在控制台上显示每个 JSON。我没有收到任何错误,但我只能显示带有最后一个索引项的最后一个 JSON (noobs2ninjas)。

谁能解释一下为什么?如何获得我需要的所有 JSON?

谢谢

【问题讨论】:

  • 当你认为你已经掌握了 XMLHR 的窍门时,它正等着你:-/

标签: javascript json ajax for-loop


【解决方案1】:

谁能解释我为什么?如何获得我需要的所有 JSON?

为了发送第二个请求,您需要等待第一个请求完成。因此,如果您有兴趣按数组顺序获取响应,您可以在每个数组元素上循环,只有当您获得响应时,您才能在其余元素上循环:

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var request = new XMLHttpRequest();
(function loop(i, length) {
    if (i>= length) {
        return;
    }
    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    request.open("GET", url);
    request.onreadystatechange = function() {
        if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
            var data = JSON.parse(request.responseText);
            console.log('-->' + i + ' id: ' + data._id);
            loop(i + 1, length);
        }
    }
    request.send();
})(0, index.length);

相反,如果您想完全异步(以并发方式)执行所有请求,则必须在循环内声明和限定 request 变量。每个数组元素有一个请求。您有一些可能性,例如:

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];


for (var i = 0; i < index.length; i++) {

    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    let request = new XMLHttpRequest();
    request.open("GET", url);
    request.onreadystatechange = function() {
        if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
            var data = JSON.parse(request.responseText);
            console.log('-->' + data._id);
        }
    }
    request.send();
}

根据@Wavesailor 评论,为了在调用结束时进行数学计算:

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var request = new XMLHttpRequest();
(function loop(i, length, resultArr) {
    if (i>= length) {
        console.log('Finished: ---->' + JSON.stringify(resultArr));
        return;
    }
    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];

    request.open("GET", url);
    request.onreadystatechange = function() {
        if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
            var data = JSON.parse(request.responseText);
            console.log('-->' + i + ' id: ' + data._id);
            resultArr.push(data._id);
            loop(i + 1, length, resultArr);
        }
    }
    request.send();
})(0, index.length, []);

【讨论】:

  • 使用“onreadystatechange”和“onload”有什么区别?
  • @Dema 您需要等待操作正确完成,而load:当资源及其依赖资源完成加载时会触发加载事件。
  • 我还不明白为什么循环函数能够保持数组元素的设置顺序(在我看来,这正是 for 循环会做的事情)但它做了什么你说所以我想我只需要更彻底地考虑一下。谢谢你给我两个选择
  • @gaetanoM 很好的例子,但我能否请你更详细地解释第一个 - 我对你定义函数 loop 的方式以及它的调用方式感到迷惑。此外,我将如何创建一个函数,该函数将使用 Ajax 调用的结果来计算将显示的内容,即只有在我获得 Ajax 调用的所有值后才能计算。
  • @Wavesailor 在答案中添加了最后一个 sn-p。我希望它有所帮助。谢谢
【解决方案2】:

问题是你声明

var request = new XMLHttpRequest();

for 循环之外。所以你只实例化一个请求。

您必须将它包含在 for 循环中。

另外,不要忘记 ajax异步 执行的,因此您会以 随机 顺序获得结果。

i 变量的值必须使用 let 关键字声明才能声明 块范围 局部变量。

let 允许您将限制在范围内的变量声明到

let 始终用作closures 的解决方案。

此外,您可以使用array 来存储XMLHttpRequest

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
requests=new Array(index.length);
for (let i = 0; i < index.length; i++) {
    var url = "https://wind-bow.glitch.me/twitch-api/channels/" + index[i];
    requests[i] = new XMLHttpRequest();
    requests[i].open("GET", url);
    requests[i].onload = function() {
        var data = JSON.parse(requests[i].responseText);
        console.log(data);
    }
    requests[i].send();
}

【讨论】:

  • 我试过了,但是我得到了这个错误:Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse () at XMLHttpRequest.request.onload
  • 尽量不要解析您的回复。看起来您的回复之一的 JSON 格式不正确
  • @NikitaMalyschkin,我用最终解决方案更新了我的答案。
  • 谢谢。现在我明白了
  • 我最近对其进行了更改以处理对 NOAA 的两个请求,并且它立即起作用。谢谢。将有助于在您的代码 IMO 中包含一些处理请求数据的方法。
【解决方案3】:

您可能还喜欢使用Fetch API 代替XMLHttpRequest。那么你所要做的就是利用几个Promise.all()函数。

var index = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"],
    url   = "https://wind-bow.glitch.me/twitch-api/channels/",
    proms = index.map(d => fetch(url+d));

Promise.all(proms)
       .then(ps => Promise.all(ps.map(p => p.json()))) // p.json() also returns a promise
       .then(js => js.forEach((j,i) => (console.log(`RESPONSE FOR: ${index[i]}:`), console.log(j))));
.as-console-wrapper {
max-height: 100% !important;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-17
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多