It probably doesn't matter on modern browsers, but fundamentally, it's so you set up the call before sending it. In particular, so that all the handlers have been attached before asking the XHR to do something. Compare:
// Example 1
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function() {
// Got the data
});
xhr.open("GET", "http://example.com");
xhr.send();
with
// Example 2
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com");
xhr.send();
xhr.addEventListener("load", function() {
// Got the data
});
Browsers are not single-threaded, though they run JavaScript code in a single main thread (plus any web workers you create). So it's possible (though extraordinarily unlikely) that with Example 2, if the resource is in the browser's cache, a separate thread handling network calls could trigger the load
event between the send
and addEventListener
calls on the JavaScript thread, see that there were no handlers registered, and not queue a task for the event loop to call the handler. Whereas with Example 1, if it triggers the load event immediately upon send
, it sees an attached handler and queues a task to call it (which runs later, when the event loop comes around to processing that task).
Here's an example of that hypothetical scenario, showing the thread interaction:
Example 1 - Highly Theoretical Scenario
JavaScript Thread Network Thread
----------------------------------------- --------------
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function() {
// Got the data
});
xhr.open("GET", "http://example.com");
xhr.send();
(Within send: Start the send, handing
off to the network thread)
1. Start a GET on `xhr`
2. It's in cache, are there any load
handlers registered on `xhr`?
3. Yes, queue a task to call the handler
(Done with current task)
(Pick up next task)
Call the handler
vs
Example 2 - Highly Theoretical Scenario
JavaScript Thread Network Thread
----------------------------------------- --------------
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com");
xhr.send();
(Within send: Start the send, handing
off to the network thread)
1. Start a GET on `xhr`
2. It's in cache, are there any load
handlers registered on `xhr`?
3. No, don't queue a task to call
the handler
xhr.addEventListener("load", function() {
// Got the data
});
(Done with current task)
(Pick up next task)
(No task, do nothing)
I very much doubt any current browser would actually do that (Example 2), and I'm not aware of XHR having had a problem like this in the past. But it's theoretically possible, and there was a very similar problem, circa 2008, with setting src
on an img
element before hooking the load
event for it. However, browsers fixed that problem, and I'd be surprised to find they were open to the Example 2 scenario above now, either, even if they or may not have been at some point in the past.
In practice, I doubt it matters. But I'd still use Example 1 if I used XMLHttpRequest
(I don't, I use fetch
).