我想用for循环循环100次ajax请求。这是我的代码:
for(var i=1; i<100; i++)
{
var num = i+1;
var request = new XMLHttpRequest();
request.open("GET", "http://localhost/test/1/2/main.php?t="+num+"", true);
request.send(null);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var parser = new DOMParser();
var doc = parser.parseFromString(request.responseText, "text/html");
var rows = doc.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0].getElementsByTagName("tr");
var sum = 0;
for(var j=0; j<rows.length;j++)
{
sum += parseInt( rows[j].getElementsByTagName("td")[7].textContent.trim() );
}
alert(num);
}
}
}
但它不起作用。 在控制台中,我看到100次这个信息:
XHR完成加载:GET“http://localhost/test/1/2/main.php?t=2”。 XHR完成加载:GET“http://localhost/test/1/2/main.php?t=3”。
等。所以一切都应该没问题。 但我只看到警报14次(我现在不知道为什么14次),没有100次。
为什么这个程序不起作用?
答案 0 :(得分:0)
请在下面的代码。这将允许仅在上一次完成之后触发ajax调用。所以不会错过任何ajax电话。
<script type="text/javascript">
var num = 0;
doAjax(0);
function doAjax(arrCount)
{
if(num<100){
num += 1;
var request = new XMLHttpRequest();
request.open("GET", "http://localhost/test/1/2/main.php?t="+num+"", true);
request.send(null);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var parser = new DOMParser();
var doc = parser.parseFromString(request.responseText, "text/html");
var rows = doc.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0].getElementsByTagName("tr");
var sum = 0;
for(var j=0; j<rows.length;j++)
{
sum += parseInt( rows[j].getElementsByTagName("td")[7].textContent.trim() );
}
alert(num);
doAjax(num)
}
}
}
}
</script>
答案 1 :(得分:0)
使用IIFE进行闭包的替代方法,以及一些更高级的DOM和Array方法,使事情变得更加整洁(在我看来)
for(var i=1; i<100; i++) {
(function(num) { // [1]
var request = new XMLHttpRequest();
request.open("GET", "http://localhost/test/1/2/main.php?t="+num+"", true);
request.addEventListener('load', function() {
var parser = new DOMParser();
var doc = parser.parseFromString(request.responseText, "text/html");
var sum = [].map.call( // [2]
doc.querySelector("table").querySelectorAll("tbody>tr>td:nth-child(8)"), //[3]
function(cell) { // [4]
return parseFloat(cell.textContent.trim());
}).reduce(function(a, b) { // [5]
return a + b;
});
alert(num);
});
request.send(null);
}(i + 1));
}
说明:
[1]
function(num) {
...
}(i + 1));
这是一个IIFE,它为i + 1(作为num)
的值创建一个闭包[2]
[].map.call(x, fn)
这将创建一个来自&#34; x&#34;的数组。并使用回调fn调用map函数 - 我们需要这样做,因为下一部分的结果不是数组,而是NodeList。
代码x中的是
[3]
doc.querySelector("table").querySelectorAll("tbody>tr>td:nth-child(8)")
这得到第一个表,然后是每个tbody中每个tr的第8个TD
如果返回的html只是一个表,则可以将上面的内容更改为
doc.querySelectorAll("table>tbody>tr>td:nth-child(8)")
[4]现在,fn在地图回调中是
function(cell) {
return parseFloat(cell.textContent.trim());
}
这将获取每个单元格,并返回解析为float
的内容[5]现在我们有一个浮点数组 - 获取数组数的总和的最简单方法是使用Array#reduce
.reduce(function(a, b) {
return a + b;
});
所以,现在总和,在一个复杂的陈述中得到了单元格的总和
我使用request.addEventListener('load', fn)
...与request.onload = fn
相同 - 这是我的个人怪癖,可能会弄乱OLD Internet Explorer用户:p
load
被解雇...所以不再需要readyState体操