【问题标题】:XMLHttpRequest in for loop循环中的 XMLHttpRequest
【发布时间】:2014-08-09 16:09:50
【问题描述】:

我正在尝试在 for 循环中发出多个服务器请求。我找到了this question 并实施了建议的解决方案。但是,它似乎不起作用。

    for (var i = 1; i <= 10; i++)
    {
    (function(i) {
    if(<some conditions>)
    {
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp[i]=new XMLHttpRequest();
      } else { // code for IE6, IE5
        xmlhttp[i]=new ActiveXObject("Microsoft.XMLHTTP");
      }
      xmlhttp[i].onreadystatechange=function() {
        if (xmlhttp[i].readyState==4 && xmlhttp[i].status==200) {
          document.getElementById("preselection").innerHTML=xmlhttp[i].responseText;
        }
      }
      xmlhttp[i].open("GET","getBuoys.php?q="+i,true);
      xmlhttp[i].send();
    }
})(i);
}

如果我删除 for 循环并将所有 xmlhttp[i] 更改为 xmlhttp,对于一个元素来说一切正常,但我无法发出多个请求。提前感谢您的任何建议。

【问题讨论】:

  • 查看下面的答案或查看此答案sending-post-request-in-for-loop 以获得进一步的解释。
  • 您是否将xmlhttp 定义为某处的数组?如果是,您收到的错误消息是什么?如果不是,为什么不将每个 xmlhttp 都设置为闭包范围?

标签: javascript ajax xmlhttprequest


【解决方案1】:

试试下面的sn-p

// JavaScript
window.onload = function(){

    var f = (function(){
        var xhr = [], i;
        for(i = 0; i < 3; i++){ //for loop
            (function(i){
                xhr[i] = new XMLHttpRequest();
                url = "closure.php?data=" + i;
                xhr[i].open("GET", url, true);
                xhr[i].onreadystatechange = function(){
                    if (xhr[i].readyState === 4 && xhr[i].status === 200){
                        console.log('Response from request ' + i + ' [ ' + xhr[i].responseText + ']'); 
                    }
                };
                xhr[i].send();
            })(i);
        }
    })();

};

// PHP [closure.php]
echo "Hello Kitty -> " . $_GET["data"];

回应

Response from request 0 [ Hello Kitty -> 0]
Response from request 1 [ Hello Kitty -> 1]
Response from request 2 [ Hello Kitty -> 2] 

【讨论】:

  • 啊,所以错误是全局声明数组。也许这对我来说已经足够了,虽然劳伦斯琼斯的回答看起来也很好。我现在不能试试你的答案,明天再做。
  • @Axel 基本上是的 ;) 检查我在 cmets 中留下的其他参考资料,以更详细地了解这个问题,而不是使用数组。
  • +1 用于将 for 循环变量作为自调用函数变量发送,因此不受异步延迟的影响,对我有很大帮助,谢谢。
【解决方案2】:

首先,这是糟糕的格式。请提出一个小请求,以使其在将来更易于解析。

不过我们可以清理它。

var XMLHttpRequest
  = XMLHttpRequest || require('xmlhttprequest').XMLHttpRequest;

// Makes a request for 4 buoy page responses.
requestAllBuoys(4, function(requests) {

  console.log('Got results!');

  // Take out the responses, they are collected in the order they were
  // requested.
  responses = requests.map(function(request) {
    return request.responseText;
  });

  // Left to you to implement- I don't know what you're going to do with
  // your page!
  updateDom(responses);

});

// Makes request to all buoy url's, calling the given callback once
// all have completed with an array of xmlRequests.
function requestAllBuoys (n, cb) {

  var latch = makeLatch(n, cb);

  makeBuoyURLTo(n).map(function (url, i) {
    startXMLRequest('GET', url, latch.bind(undefined, i));
  });

}

// Generates a latch function, that will execute the given callback
// only once the function it returns has been called n times.
function makeLatch (n, cb) {

  var remaining = n,
      results = [],
      countDown;

  countDown = function (i, result) {
    results[i] = result;
    if (--remaining == 0 && typeof cb == 'function') {
      cb(results);
    }
  }

  return countDown;

}

// Generates an array of buoy URL's from 1 to n.
function makeBuoyURLTo (n) {

  var i, buoyUrls = [];

  for (i = 1; i <= n; i++) {
    buoyUrls.push('getBuoys.php?q=' + i);
  }

  return buoyUrls;

}

// Create and initiate an XMLRequest, with the given method to the given url.
// The optional callback will be called on successful completion.
function startXMLRequest (method, url, cb) {

  var xmlRequest = createXMLRequest();

  xmlRequest.onreadystatechange = function () {
    if (isXMLFinished(xmlRequest)) {
      if (cb && typeof cb == 'function') {
        cb(xmlRequest, method, url);
      }
    }
  }

  xmlRequest.open(method, url, true);
  xmlRequest.send();

  return xmlRequest;

}

// Initiates an XMLRequest from either HTML5 native, or MS ActiveX depending
// on what is available.
function createXMLRequest () {

  var xmlRequest;

  if (XMLHttpRequest) {
    xmlRequest = new XMLHttpRequest();
  } else {
    xmlRequest = new ActiveXObject('Microsoft.XMLHTTP');
  }

  return xmlRequest;

}

// Verifies that XMLRequest has finished, with a status 200 (OK).
function isXMLFinished (xmlRequest) {
  return (xmlRequest.readyState == 4) && (xmlRequest.status == 200);
}

这可能看起来更长,但它使事情变得无限清晰,而你花在制作它上的时间就是你不花时间调试的时间。

它还允许您按照它们作为标准数组出现的顺序一起访问最终结果。这是主要添加的批量。

我想说你很清楚你在这里实际在做什么,至于你的代码唯一不能工作的就是更新 dom(当然你'将只是将它们快速分配到同一个元素中?每次都互相替换......)。

如果您仍在苦苦挣扎,请查看 answer 关于处理异步回调的信息。但是,为了您自己,请保持您的代码更干净。

【讨论】:

  • 我明天一有时间就试试这个。顺便说一句,看起来非常漂亮且井井有条!
猜你喜欢
  • 1970-01-01
  • 2018-03-24
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
相关资源
最近更新 更多