Full disclosure: I'd qualify myself as having intermediate JavaScript knowledge. So this is slightly above my experience level at this time.
I've got a Google Chrome Extension that does an AJAX request for a local file:///
as soon as a page loads. After I get the response back from the request I use the returned code in several functions later on in my code. Most of the time I get the response back before my code that needs it runs. But sometimes I don't and everything breaks.
Now, I assume I could just throw all of the relevant code inside of the xhr.onload
below. But that seems really inefficient? I have a lot of moving parts that rely on the response and it seems bad to put them all in there.
I've perused several articles related to async/await and I'm having trouble grasping the concept. I'm also not 100% positive I'm looking at this the right way. Should I even be considering using async/await?
Here is the code for my AJAX request.
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onload = function(e) {
code = xhr.response;
};
xhr.onerror = function () {
console.error("** An error occurred during the XMLHttpRequest");
};
xhr.send();
Let's say I've got a bunch of functions that need to fire afterwards later on in my code. Right now they just look like:
function doTheThing(code) {
// I hope the response is ready.
}
What's the best way to approach this? FYI, the Fetch
API isn't an option.
Here's a high level view of how my code is structured.
// AJAX request begins.
// ...
// A whole bunch of synchronous code that isn't dependant on
// the results of my AJAX request. (eg. Creating and appending
// some new DOM nodes, calculating some variables) I don't want
// to wait for the AJAX response when I could be building this stuff instead.
// ...
// Some synchronous code that is dependant on both my AJAX
// request and the previous synchronous code being complete.
// ...
// Some more synchronous code that needs the above line to
// be complete.
I usually do async/await like this:
async function doAjaxThings() {
// await code here
let result = await makeRequest("GET", url);
// code below here will only execute when await makeRequest() finished loading
console.log(result);
}
document.addEventListener("DOMContentLoaded", function () {
doAjaxThings();
// create and manipulate your DOM here. doAjaxThings() will run asynchronously and not block your DOM rendering
document.createElement("...");
document.getElementById("...").addEventListener(...);
});
Promisified xhr function here:
function makeRequest(method, url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}