W3C spec建议执行后: 一些简单的代码,用于处理通过网络获取的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的行中被多次调用时的情况。我猜这种行为是正确的,因为规范说每次状态更改都必须激活事件,readyState必须始终等于当前状态,所以如果事件队列中有多个事件堆积,很明显,一个将使用readyState == 4获得多个调用。
http://jsfiddle.net/44b3P/ - 这是上面的示例,在发送请求之后使用调试器调用来暂停执行,并在processData中使用alert()。一旦取消暂停执行,您将收到3个警报。
来自w3c的这个例子似乎是在网络的多个地方复制和粘贴的 - 特别是OpenSocial似乎以这种方式处理xhr事件。这是对的吗?
答案 0 :(得分:13)
在Chrome开发者工具中进行调试时,我也看到了相同的行为(DONE 200被多次击中,即2 ... n次)。
为了使它始终处于调试模式,我找到了两个选项:
使用onload
验证XMLHTMLRequest成功W3C Spec
client.onload = handler;
此版本在IE8中不起作用。它必须是实现XMLHttpRequestEventTarget接口
在onreadystatechange
状态后立即删除DONE 200
处理程序。
client.onreadystatechange = function() {
// check if request is complete
if (this.readyState == this.DONE) {
if (this.onreadystatechange) {
client.onreadystatechange = null;
handler();
}
}
};
答案 1 :(得分:0)
我的onreadystatechange
处理程序从未执行多次readyState
为4。
我认为假设在DONE上执行一次是正确的。