質問

This is an example from Trevor Burnham's Async JavaScript:

var ajaxRequest = new XMLHttpRequest;
ajaxRequest.open('GET', url);
ajaxRequest.send(null);
while (ajaxRequest.readyState === XMLHttpRequest.UNSENT) {
// readyState can't change until the loop returns
};

Here's my understanding of what the example intends to teach: the open and send calls are asynchronous, so although the call to open queues a readystatechange event, it can't be handled until the while loop returns, so readyState can't change and this program will just hang in an infinite loop.

Here's my confusion: after looking at the W3C spec for the open method (http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-open), it looks to me that the algorithm for invoking open stipulates that a readystatechange should be fired at step 15. So given the above code, the loop will return since at the point of its execution, readyState is actually XMLHttpRequest.OPENED. What would actually make the program hang is:

var ajaxRequest = new XMLHttpRequest;
ajaxRequest.open('GET', url);
ajaxRequest.send(null);
while (ajaxRequest.readyState === XMLHttpRequest.OPENED) {
// readyState can't change until the loop returns
};

My question: is this correction correct? Also, is open also asynchronous or just send? It seems like open must be synchronous in order for it to change the readyState before the loop is entered in the original example. That would make sense to me since all it's doing is set a bunch of attributes.

役に立ちましたか?

解決

is this correction correct?

Yes, it is. The open method, whose specification you have linked, does set the readyState to OPEN synchronously. You can test this by simply logging the property value before and after you've called the method. The first loop (with the readyState === UNSENT) will simply break and not even enter the body, only your corrected one will produce an infinite loop.

Also, is open also asynchronous or just send?

(Assuming an asynchronous request). Both methods return immediately.

open does set the readystate to OPENED synchronously. It also synchronously dispatches a readystatechange event immediately after that (before it returns).

send does set the sent flag to true synchronously. There is no "SENT" readystate, so it does not fire an event for that. It does however fire a loadstart progess event (before it returns).

When the response is asynchronously received, tasks are queued in the event loop to switch the readystate again; these events will be asynchronous.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top