使用readyState = DONE,XHR可以多次触发onreadystatechange吗? [英] Can XHR trigger onreadystatechange multiple times with readyState=DONE?

查看:107
本文介绍了使用readyState = DONE,XHR可以多次触发onreadystatechange吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

W3C规范建议实施后:
一些简单的代码,用于处理通过网络获取的XML文档中的数据:

The W3C spec suggest following implementation: Some simple code to do something with data from an XML document fetched over the network:

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();

这种实现是否真的正确?

Is this implementation really correct?

在调试过程中,我发现当readystatechanged事件处理程序连续多次调用并具有相同值readyState == 4时的情况。我猜这种行为是正确的,正如规范所说,状态的每次更改都必须触发事件,而readyState必须始终等于当前状态,所以如果事件队列中有多个事件堆积,那么很明显,一个将使用readyState == 4获得多个调用。

During debug I found cases when the readystatechanged event handler is called more than once in a row with the same value of readyState == 4. I guess this behavior is correct, as specs says that each change of state must fire the event, and that readyState must always be equal to current state, so if several events pile up in the events queue, it's quite obvious, that one will get multiple calls with readyState == 4.

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

http://jsfiddle.net/44b3P/ -- this is the above example augmented with debugger call to pause execution just after the request is send, and with alert() in the processData. Once you unpause the execution you will get 3 alerts.

来自w3c的这个例子似乎是在网络的多个地方复制和粘贴 - 特别是OpenSocial似乎处理xhr这样的事件。这是正确的吗?

This example from w3c seems to be copy&pasted in multiple places in the web -- in particular OpenSocial seems to handle xhr events this way. Is it correct?

推荐答案

我也看到了相同的行为(DONE 200遭遇不止一次,即2 ... n在Chrome开发者工具中进行调试时。

I also saw the same behavior (DONE 200 being hit more than once, i.e. 2...n times) when debugging in Chrome Developer Tools.

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

To make it work always in debug mode as well, I found two options:


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

  1. Use onload to verify the success of an XMLHTMLRequest W3C Spec

client.onload = handler;

client.onload = handler;

此版本在IE8中不起作用。它必须是一个实现 XMLHttpRequestEventTarget 界面的浏览器

This version will not work in IE8. It must be a browser that implements the XMLHttpRequestEventTarget interface

只要有 DONE 200 状态,就删除 onreadystatechange 处理程序。

Remove the onreadystatechange handler as soon as you have a DONE 200 state.

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


我还在 Chromium 针对此问题,提供小提琴(谢谢!)

I have also opened an issue in Chromium for this problem, providing your Fiddle (Thanks!)

这篇关于使用readyState = DONE,XHR可以多次触发onreadystatechange吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆