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

これで、毎回、どのURLが呼び出されたreadyState = 4かの正しい値を警告する必要があります。i現在、アラートは1回だけで、出力アラートは5

4

4 に答える 4

4

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

または、の外にxhrを作成してwith追加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 に答える