如何使用多个XMLHttpRequest?

Dem*_*ema 7 javascript ajax json for-loop

我需要从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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

gae*_*noM 9

谁能解释我为什么?如何获取所需的所有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);
Run Code Online (Sandbox Code Playgroud)

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

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();
}
Run Code Online (Sandbox Code Playgroud)

根据@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, []);
Run Code Online (Sandbox Code Playgroud)


Mih*_*nut 5

问题是你申报了

var request = new XMLHttpRequest();
Run Code Online (Sandbox Code Playgroud)

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

你必须将它包含在for循环中.

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

i必须使用let关键字声明变量的值,以声明块范围局部变量.

let允许你声明了在有限的变量范围.

let始终用作闭包的解决方案.

此外,您可以使用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();
}
Run Code Online (Sandbox Code Playgroud)


Red*_*edu 5

您可能还喜欢使用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))));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper {
max-height: 100% !important;
}
Run Code Online (Sandbox Code Playgroud)