- From: Jonas Sicking <jonas@sicking.cc>
- Date: Fri, 4 Dec 2009 14:30:02 -0800
On Fri, Dec 4, 2009 at 9:52 AM, Alexey Proskuryakov <ap at webkit.org> wrote: > > On 04.12.2009, at 4:12, Anne van Kesteren wrote: > >>> On the other hand, it can't possibly work like XMLHttpRequest - for >>> whatever reason, the Web Sockets spec says that events are posted >>> asynchronously. Maybe I'm not the last an only one to get confused by this >>> difference from XMLHttpRequest events. >> >> XMLHttpRequest network events are "asynchronous" too. > > > Looks like the spec says so now. Does any browser post XMLHttpRequest events > asynchronously? This change in the spec is not harmless, as it seems to make > readystatechange event pretty much useless. Depends which events we are talking about. Events that are fired as a result of network activity is inheritly asynchronous since network events arrive asynchronously. For example "progress" events or "load" events. Other events must be synchronous, for example the "readystatechange" event that is fired during the call to XMLHttpRequest.open, or the "loadstart" event fired from XMLHttpRequest.send must be fired synchronously. However for the events that are fired as a result of network activity, I see no reason to fire these events asynchronously from that code. I.e. when a network request is finished, XMLHttpRequest takes several actions: * Sets readystate to 4 * Fires "readystatechange" * Fires "load" * Fires "loadend" * Makes responseXML non-null I see no reason to make these events be fired asynchronously *from the code that takes all these actions*. In other words, I think the XMLHttpRequest implementation should look something like: XMLHttpRequest::OnRequestDone(status) { if (status != success) { ... error handling ... return; } if (isXMLContentType(contentType)) { responseXML = parseAsXML(responseText); } readystate = 4; synchronousDispatch("readystatechange"); synchronousDispatch("load"); synchronousDispatch("loadend"); } Another way to look at it is that I think the following code: xhr = new XMLHttpRequest; timerId = setInterval(function() { if(xhr.responseXML) alert(xhr.responseXML); }, 0); xhr.open(...); xhr.send(); xhr.onloadend = function() { cancelInterval(timerId); } should never ever fire the alert. The whole purpose of firing events asynchronously is to aid implementations so that they don't need to have a deep callstack when the event fires, but instead can ensure to be in a stable state when firing the event. However if the code in question is already started asynchronously, such as as a result of a network event, then there is no reason not to fire synchronously. Firing events asynchronously always introduces hassles. Typically that conditions change between when the event was scheduled to be fired, and when the event actually fires. Many times this means that you have to keep track of the task that will fire the event and under certain conditions cancel it if what the event indicates is no longer true. Thus I think we should as a general rule try to fire synchronously when this doesn't risk destabilizing implementations. / Jonas
Received on Friday, 4 December 2009 14:30:02 UTC