我是js的新手,正在尝试在同一函数中执行多个Get请求
我的代码如下:
...
...
...
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if(this.readyState == 4 && this.status == 200){
var response = JSON.parse(xhttp.responseText);
...
...
for(var i=0; i<response.length,i++)
{
...
var xhttp1 = new XMLHttpRequest();
xhttp1.onreadystatechange = function(){
if(this.readyState == 4 && this.status == 200){
var response1 = JSON.parse(xhttp1.responseText);
...
...
...
}
};
xhttp1.open("GET","changedFileForTheInnerRequest",true);
xhttp1.send();
...
...
}
...
}
};
xhttp.open("GET","fileForTheOuterRequest",true);
xhttp.send();
我的问题: 我知道这可能看起来很奇怪,但这似乎是我唯一的选择。
我正在主请求中生成第二个GET请求, 由于某种原因,当内部代码结束时,js代码停止了,并且似乎认为他已经到了尽头。 我是html和js的新手,所以也许这就是请求的工作方式。
总而言之,当名称根据i索引和第一个请求中加载的第一个文件中的信息而更改时,我试图在第二个GET请求中获取一些不同的文件,该请求处于for循环中..
问题在于,当第一个循环结束时,它再也不会循环,并且在第一个内部get的结尾处保持堆栈。
如果您能帮助我,给我替代方案或只是解释更多,将非常高兴
谢谢!
答案 0 :(得分:0)
使用var
关键字时,变量的范围绑定到最接近的函数范围。
在此示例中
xhttp.onreadystatechange = function() {
....
....
for(var i=0; i<response.length,i++) {
.....
var xhttp1 = new XMLHttpRequest();
与
相同xhttp.onreadystatechange = function() {
var xhttp1;
....
....
for(var i=0; i<response.length,i++) {
.....
xhttp1 = new XMLHttpRequest();
xhhtp1
在xhttp.onreadystatechange
的整个范围内可用,因为这是最接近的函数范围。因此,从技术上讲,对于for循环的每次迭代,您都在用新的xhttp1
请求编写XMLHttpRequest
。
为了解决此问题,您必须将每个相应的请求包装到其自己的函数范围中。
选项2 -使用let
而不是var
来创建块范围。 (在大多数最新的浏览器版本中都可以使用,但是对于较旧的浏览器需要使用编译器。)
...
...
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(xhttp.responseText);
...
...
for (var i = 0; i < response.length, i++) {
sendRequest(response[i]);
}
...
}
};
xhttp.open("GET", "fileForTheOuterRequest", true);
xhttp.send();
function sendRequest(resp) {
// resp is the response that corresponds
// to the outer request
var xhttp = new XMLHttpRequest();
xhttp1.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(xhttp1.responseText);
...
...
...
}
};
xhttp1.open("GET", "changedFileForTheInnerRequest", true);
xhttp1.send();
}