1
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,它都应该提醒调用哪个 URL 的正确值i。目前,它只警报一次,输出警报是5

4

4 回答 4

4

如果要使用withto retain 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);
        }
    }
} 

或者您需要在外部创建 xhrwith并添加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());
} 
于 2012-10-28T18:31:28.167 回答
1

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

for(var i = 0; i < 5; i ++) (function(i) {
        [..] alert(i) [..]
})(i);
于 2012-10-28T18:20:16.167 回答
1

只需更新 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更新了它,这应该工作

于 2012-10-28T18:34:07.890 回答
0

这就是我爱它的方式

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

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

于 2012-10-28T19:00:33.343 回答