【问题标题】:Call Ajax inside for Loop在 for 循环中调用 Ajax
【发布时间】:2012-10-18 04:13:49
【问题描述】:
for (var i = 0; i < 5; i++) {
    with (x = new XMLHttpRequest()) open("GET","d.php?id=" + i), send(null), onreadystatechange = function() {
       if (x.readyState == 4 && x.status == 200) alert(i);
    }
}

现在我希望每次当readyState = 4 时,它应该提醒正确的i 值,该URL 被调用。目前只alert一次,输出alert是5

【问题讨论】:

  • 有趣的语法。以前从未见过with 在现实生活中以这种方式使用过。
  • 出于各种原因,您应该避免使用with。严格模式下会报错。
  • 感谢 cmets 伙计们,但我真正的问题是别的。
  • @Wasim:这就是为什么它是评论而不是答案;)

标签: javascript ajax loops for-loop call


【解决方案1】:

这是因为闭包捕获了i 变量本身,而不仅仅是当前值。我个人会做类似的事情:

for(var i = 0; i < 5; i ++) (function(i) {
        [..] alert(i) [..]
})(i);

【讨论】:

  • 这个不工作,你能粘贴准确的代码,
【解决方案2】:

如果您想使用with 来保留i,则需要将其添加到同时引用xhr 对象的对象中:

for(var i=0;i<5;i++){
    with({i:i, xhr:new XMLHttpRequest()}) {
        xhr.open("GET","d.php?id=" + i);
        xhr.send(null);
        xhr.onreadystatechange=function(){
            if (xhr.readyState == 4 && xhr.status == 200)
                alert(i);
        }
    }
} 

或者您需要在 with 之外创建 xhr 并将 i 添加到其中。

var xhr;
for(var i=0;i<5;i++){ 
    (xhr = new XMLHttpRequest()).i = i;
    with(xhr) {
        open("GET","d.php?id=" + i);
        send(null);
        onreadystatechange=function(){
            if (readyState == 4 && status == 200)
                alert(i);
        }
    }
} 

但是,如果您想要一个合适的、面向未来的解决方案,请将处理程序置于一个变量范围内,以提供处理程序所需的变量。

function doRequest(i, xhr) {
    xhr.open("GET","d.php?id=" + i);
    xhr.send(null);
    xhr.onreadystatechange=function(){
        if (xhr.readyState == 4 && xhr.status == 200)
            alert(i);
    }
}

然后这样称呼它:

for(var i=0;i<5;i++){
    doRequest(i, new XMLHttpRequest());
} 

或者如果你坚持像某些人那样内联函数,你可以这样做:

for(var i=0;i<5;i++){
    (function (i, xhr) {
        xhr.open("GET","d.php?id=" + i);
        xhr.send(null);
        xhr.onreadystatechange=function(){
            if (xhr.readyState == 4 && xhr.status == 200)
                alert(i);
        }
    }(i, new XMLHttpRequest());
} 

【讨论】:

  • 嗨,您的回答帮助解决了我遇到的问题,但我不知道为什么-希望您能解释一下-我最初在 for 循环中拥有doRequest 的所有代码,但只有最后一个请求会通过。我在这样的循环中创建了一个新请求 var request = new XMLHttpRequest() 。一旦我将其分离到另一个函数中并传递了所需的变量,一切就都奏效了。为什么是这样?以前没有遇到过这样的情况。感谢您的帮助!
【解决方案3】:

只需更新 James 代码以满足您的需求

for (var i = 0; i < 5; i++) {
    with (x = new XMLHttpRequest()) open("GET","d.php?id=" + i), send(null), onreadystatechange = (function(i, x) {
        return function () {
        if (x.readyState == 4 && x.status == 200) alert(i);
       }
    })(i, x)
}

希望对你有帮助

x 更新了它,这应该可以工作

【讨论】:

  • 你仍在循环中覆盖x
  • withstrict mode 中已弃用
【解决方案4】:

这就是我喜欢它的方式

var x = new Array();
for (var i = 0; i < 5; i++) {
    with (x[i] = new XMLHttpRequest()) open("GET","d.php?id=" + i), send(null), onreadystatechange = (function(i) {
        return function () {
        if (x[i].readyState == 4 && x[i].status == 404) alert(i);
       }
    })(i)
}

但我对使用闭包解决我的问题更感兴趣,我如何使用闭包来解决我的问题。

【讨论】:

  • 如果要使用闭包,不妨利用变量作用域,去掉with。我用适当的闭包示例更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-31
相关资源
最近更新 更多