Learning Asynchronous JavaScript
As we all know, JavaScript code is Synchronous and Single-threaded and we can think of our JavaScript code as a list of instructions that our browser completes one by one. It basically runs the code line by line where each line must be completed before the next one starts, and this can be referred to as an event loop.
Asynchronous code is anything that gets queued up on another queue and not on the event loop so other statements/code can be run without the async code blocking the event loop. For example, you may want to prepare a meal and also do the dishes, you don’t have to wait until the food is ready before you wash your dishes you can do it while the food gets cooked. Sending an HTTP request is like cooking, the request takes a certain amount of time to complete but then the event loop has already moved on to the next line of code. We will learn about three of the most common ways of handling asynchronous code and how to implement them.
We’re going to use the setTimeOut function to show some of the problems we can run into if we’re not careful with the asynchronous code.
In this example, we created a variable called “xander” with a string in it and then a function called getSet, that’s going to use the setTimeOut function to modify the contents of this variable and we passed in 500ms as the second argument. We call the function getSet and it gives us the value of the variable, “Get Ready”. This is one of the problems of asynchronous code because the JavaScript starts to run the function but then moves to the next line before the function could finish executing based on the specified time, so we don’t get to see the result of the function. This will also happen regardless of the time set for the setTimeOut function to run. Now we’ll talk about how to deal with asynchronous code.
Callbacks
Callback functions can be referred to as the old school method of writing asynchronous code. Callbacks are passed as an argument to an asynchronous function and called when all the asynchronous activities are done.
To implement the callback to our getSet function, we need to add the callback as an argument to our getSet function and this argument would be of type function which will allow us to call it within the setTimeOut function and then execute it after 500ms. We proceed to add the callback function to our getSet call and then add an anonymous function that changes the textContent of “ xander”. To test what we’ve done, we refresh the page and get the value “Get Ready!!” which then changes to “All Set!!” after the specified execution time has elapsed which in this case is 500ms.
Using a lot of callbacks can lead to something known as callback hell as we tend to have lots of nested code that’s usually hard to read. Now we’ll talk about a method that helps us write neat code asynchronously.
Promises
A promise is an object that may produce a single value some time in the future. It takes an anonymous function which in turn takes two arguments, resolve and reject. Resolve for when the promise returns valid data and Reject when it encounters an error. Promises serve the same purpose as callbacks but they’re a bit more powerful.
Promises are great for asynchronous programming especially when you don’t want the JavaScript to block the execution of the code for example, when we make API requests, we use a promise so the task can happen in the background. We append .then to the promise whenever we have a function that we want to call after the promise has been resolved.
Async/Await
An async function is a function that returns a promise. It is quite similar to promises but their syntaxes differ. Promises have .then that we have to chain to our code but the async function uses async and await to achieve the same aim. In simpler terms, the await keyword basically says “Pause the function till I have something”. Note that we use the await keyword in front of any function that returns a promise and the await keyword can only work in a function marked as async. Once the promise is resolved, the function moves to the next line and awaits the next move.
In the example above, we declared a new async function and created a new const which gets the promise returned by the getSet function. This function will wait for the promise to resolve and then set the textContent to what was resolved by the promise. In summary, we have an async function that gets a promise from our function, waits for a response, and once it resolves it sets the textContent to what was resolved by the promise. This method makes code easier to read and maintain.
Conclusion
We covered the basics of asynchronous code and talked about three different methods of implementation:
Callbacks: This is the old school method and it is passed as an argument to an asynchronous function. It is essential we learn this method.
Promises: This is a very common technique as it is widely used, and it produces a single value sometime in the future.
Async/Await: This method uses promises but in a more readable and easy to understand way.