-1

私が書いているクロム拡張機能では、 localStorage に保存したいくつかのオブジェクトをサーバーに対して検証する必要があります。このために、各 localstorage 要素のデータを単純に送信し、 response で何かを行う必要がある for ループを作成しました。コードは次のようなものです。

 for (var key in localStorage) {
        if (! some condition )
                      continue;

        var httpRequest = new XMLHttpRequest();
        httpRequest.onreadystatechange = function() {
            if (httpRequest.readyState === 4 && httpRequest.response == 200) {
                do something with 'key' from the for loop
            }
        }
        };
        var url = BASE_PATH ;
        httpRequest.open("POST", url);
        httpRequest.send(some data);
                     }

ただし、デバッグ中に、ajax 応答では、for ループからの「キー」は必要なキーではないようです。各 ajax 呼び出しに一致する for ループから同じキーを取得することを期待していましたが、取得したのはすべての ajax 呼び出しで同じキー。私は何か間違ったことをしていますか、それとも不可能なことを期待していますか? ajax はクロージャー関数内にあるため、値はメモリまたはそのようなものに保持されると思いました。

4

1 に答える 1

1

実際の Ajax 呼び出しを別の関数に抽出します。

function AjaxCall( key ) {
  var httpRequest = new XMLHttpRequest();
  httpRequest.onreadystatechange = function() {
    if ((httpRequest.readyState === 4) && (httpRequest.response == 200)) {
      do something with 'key' from the for loop
    }
  };
  var url = BASE_PATH ;
  httpRequest.open("POST", url);
  httpRequest.send(some data);
}

for (var key in localStorage) {
  if ( some condition ) {    
    AjaxCall( key );
  }    
}

理由は、に渡された関数でクロージャを作成しているためonreadystatechangeです。これらの関数keyはすべて、ループが終了した後、すべての Ajax 呼び出しに対して 1 つの (最後の) 値を保持する同じ変数を指します。

別の関数を作成すると (AjaxCall()私の例のように)、呼び出しごとに異なるコンテキストが作成されるため、すべてのコールバックが異なるキーを指します。

于 2013-05-14T14:50:07.540 に答える