javascript 如何使用多个 XMLHttpRequest?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46503558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 06:42:56  来源:igfitidea点击:

How to use multiple XMLHttpRequest?

javascriptjsonajaxfor-loop

提问by Dema

I need to get 8 JSON from 8 different URL. I stored the query string that I have to change in an Array and I loop through it with a for loop. Here is my code:

我需要从 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();
}

So far I just want to display each JSON on the console. I don't get any error but I can display only the last JSON with the last index item (noobs2ninjas).

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

Could anybody explain me why? how do I get the all JSON that I need?

有人可以解释我为什么吗?我如何获得我需要的所有 JSON?

Thanks

谢谢

回答by gaetanoM

Could anybody explain me why? how do I get the all JSON that I need?

有人可以解释我为什么吗?我如何获得我需要的所有 JSON?

In order to send a second request you need to wait for the first to finish. Hence, if you are interested to get the responses in the array order you can loop on each array element and only when you get the response you can loop on the remaining elements:

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

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

Instead, if you want to execute all the request completely asynchronous (in a concurrent way), the requestvariable must be declared and scoped inside the loop. One requestfor each array element. You have some possibilities like:

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

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

As per @Wavesailor comment, in order to make a math computation at the end of calls:

根据@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, []);

回答by Mihai Alexandru-Ionut

The problem is that you declare

问题是你声明

var request = new XMLHttpRequest();

outside of the forloop. So you instance only one request.

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

You have to include it insidethe for loop.

您必须将其包含for 循环中。

Also, don't forget that ajaxis executed asynchronousso you will get the results in a randomorder.

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

The value of ivariable must be declared using letkeyword in order to declare a block scopelocal variable.

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

letallows you to declare variables that are limited in scopeto the block.

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

letis always used as a solution for closures.

let总是用作闭包的解决方案。

Also, you can use an arraywhere you can store the XMLHttpRequest.

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

回答by Redu

You may also prefer to use the Fetch APIin the place of XMLHttpRequest. Then all you have to do is to utilize a few Promise.all()functions.

您可能还喜欢使用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;
}

回答by peko

I just had the same issue. Just use "this.responseText" instead of "request.responseText". That's it.

我只是有同样的问题。只需使用“this.responseText”而不是“request.responseText”。而已。