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

qbo*_*lec 6 javascript xmlhttprequest

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();
Run Code Online (Sandbox Code Playgroud)

这个实现真的是对的吗?

调试过程中,我发现情况下,当readystatechanged事件处理程序与readyState的==相同的值称为不止一次在一排4我想这种行为是正确的,因为规范说,国家的每一个变化必须触发事件,以及readyState必须始终等于当前状态,因此如果事件队列中有多个事件堆积,那么很明显,一个将使用readyState == 4获得多个调用.

http://jsfiddle.net/44b3P/ - 这是上面的示例,在发送请求之后使用调试器调用来暂停执行,并在processData中使用alert().一旦取消暂停执行,您将收到3个警报.

来自w3c的这个例子似乎是在网络中的多个位置进行复制和粘贴 - 特别是OpenSocial似乎以这种方式处理xhr事件.这是对的吗?

Gab*_*vay 13

在Chrome Developer Tools中进行调试时,我也看到了相同的行为(DONE 200被多次击中,即2 ... n次).

为了使它始终在调试模式下工作,我发现了两个选项:

  1. 使用onload来验证XMLHTMLRequest成功W3C规范

    client.onload = handler;

    此版本在IE8中不起作用.它必须是实现XMLHttpRequestEventTarget接口的浏览器

  2. onreadystatechangeDONE 200状态后立即删除处理程序.

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

我也在Chromium中为这个问题开了一个问题,提供你的小提琴(谢谢!)