javascript for 循环中的 XMLHttpRequest

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25220486/
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-28 04:11:13  来源:igfitidea点击:

XMLHttpRequest in for loop

javascriptajaxxmlhttprequest

提问by Axel

I am trying to make several server requests inside a for loop. I found this questionand implemented the suggested solution. However it doesn't seem to work.

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

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

If I remove the for loop and change all xmlhttp[i] to xmlhttp, everything works just fine for one element, but I can't make several requests. Thanks in advance for any suggestions.

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

回答by hex494D49

Try the snippet below

试试下面的片段

// 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

回复

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

回答by Lawrence Jones

First thing first, that's awful formatting. A small request to keep it a bit more parseable in future please.

首先,这是可怕的格式。一个小小的请求,请让它在未来更易于解析。

We can clean this up though.

不过我们可以把它清理干净。

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

This may seem longer, but it makes things infinitely clearer, and the time you spent making it so is time you don't spend debugging.

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

It also allows you to access the final result together, in the order that they came as a standard array. This is the main added bulk.

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

I would say you have a good idea of what you're actually doing here, as to me the only thing about your code that wouldn't workis the updating of the dom (surely you'll just be assigning them rapidly all into the same element? replacing each other each time...).

我会说你很清楚你在这里实际上在做什么,对我来说,你的代码唯一不起作用的是 dom 的更新(当然你只会快速地将它们全部分配到相同的元素?每次都互相替换......)。

Have a look at this answerabout handling async callbacks if you're still struggling. But please, for your own sake, keep your code cleaner.

如果您仍在苦苦挣扎,请查看有关处理异步回调的答案。但是,为了您自己,请保持您的代码更简洁。