6

W3C 仕様では、次の実装が提案されています。ネットワーク経由でフェッチされた XML ドキュメントからデータを処理する単純なコード:

function processData(data) {
  // taking care of data
}

function handler() {
  if(this.readyState == this.DONE) {
    if(this.status == 200 &&
       this.responseXML != null &&
       this.responseXML.getElementById('test').textContent) {
      // success!
      processData(this.responseXML.getElementById('test').textContent);
      return;
    }
    // something went wrong
    processData(null);
  }
}

var client = new XMLHttpRequest();
client.onreadystatechange = handler;
client.open("GET", "unicorn.xml");
client.send();

この実装は本当に正しいですか?

デバッグ中に、readystatechanged イベント ハンドラーが同じ値の readyState == 4 で連続して 2 回以上呼び出されるケースを見つけました。仕様では、状態が変化するたびにイベントを発生させる必要があると書かれているため、この動作は正しいと思います。 readyState は常に現在の状態と等しくなければならないため、複数のイベントがイベント キューに積み重なった場合、readyState == 4 で複数の呼び出しが発生することは明らかです。

http://jsfiddle.net/44b3P/ -- これは、リクエストが送信された直後に実行を一時停止するデバッガー呼び出しと、processData 内の alert() で拡張された上記の例です。実行の一時停止を解除すると、3 つのアラートが表示されます。

この w3c の例は、Web の複数の場所でコピー & ペーストされているようです。特に、OpenSocial は xhr イベントをこの方法で処理しているようです。それが正しいか?

4

2 に答える 2

15

Chrome 開発者ツールでデバッグするときに、同じ動作 (DONE 200 が複数回、つまり 2...n 回ヒットする) も見ました。

常にデバッグ モードでも動作するようにするために、次の 2 つのオプションを見つけました。

  1. onloadXMLHTMLRequest W3C 仕様の成功を検証するために使用します

    client.onload = ハンドラ;

    このバージョンは IE8 では動作しません。XMLHttpRequestEventTargetインターフェイスを実装するブラウザである必要があります

  2. onreadystatechange状態になったらすぐにハンドラーを削除しますDONE 200

    client.onreadystatechange = function() {
        // check if request is complete
        if (this.readyState == this.DONE) {
            if (this.onreadystatechange) {
                client.onreadystatechange = null;
                handler();
            }
        }
    };
    

また、この問題についてChromiumで問題を開き、Fiddleを提供しました(ありがとう!)

于 2012-11-27T13:19:24.243 に答える
0

onreadystatechangeハンドラーを 4 で複数回実行したことはありませんreadyState

DONE での 1 回の実行は正しいと思います。

于 2012-10-06T16:54:46.790 に答える