使用readyState = DONE,XHR可以多次触发onreadystatechange吗?

时间:2012-10-06 15:49:23

标签: javascript xmlhttprequest

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事件。这是对的吗?

2 个答案:

答案 0 :(得分:13)

在Chrome开发者工具中进行调试时,我也看到了相同的行为(DONE 200被多次击中,即2 ... n次)。

为了使它始终处于调试模式,我找到了两个选项:

  1. 使用onload验证XMLHTMLRequest成功W3C Spec

    client.onload = handler;

    此版本在IE8中不起作用。它必须是实现XMLHttpRequestEventTarget接口

  2. 的浏览器
  3. onreadystatechange状态后立即删除DONE 200处理程序。

    client.onreadystatechange = function() {
        // check if request is complete
        if (this.readyState == this.DONE) {
            if (this.onreadystatechange) {
                client.onreadystatechange = null;
                handler();
            }
        }
    };
    
  4. 我还在Chromium中针对此问题打开了一个问题,提供了Fiddle(谢谢!)

答案 1 :(得分:0)

我的onreadystatechange处理程序从未执行多次readyState为4。

我认为假设在DONE上执行一次是正确的。