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.
Luckily, there is a way to make the XMLHttpRequest asynchronous, with the async parameter. We do this by changing the xhr. open(“GET”, url, false); to xhr. open(“GET”, url); because if we skip the latest parameter in the open method, the value will be true for the async parameter.
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
The await operator is used to wait for a Promise . It can only be used inside an async function within regular JavaScript code; however it can be used on its own with JavaScript modules.
Synchronous XHR is now in deprecation state. The recommendation is that developers move away from the synchronous API and instead use asynchronous requests. All new XHR features such as timeout or abort are not allowed for synchronous XHR.
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(); }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With