for循环中的Ajax请求

时间:2016-09-01 10:34:12

标签: javascript ajax

我想用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次。

为什么这个程序不起作用?

2 个答案:

答案 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体操