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 イベントをこの方法で処理しているようです。それが正しいか?