Our Thoughts

The Progression of Asynchronous JavaScript

Updated: 6 days ago


JavaScript has recently taken on some big updates in the way we handle asynchronous operations. ES6 brought us the Promise API which has improved the flow and readability of our code. We also have ES7, which has brought us the new async/await syntax on top of Promises. With all of this progression in the asynchronous world of JavaScript, it’s useful to take a step back and realize how it’s changed over the years.

Callbacks It all started with callbacks. Asynchronous JavaScript would not be possible without the use of callbacks. They are nothing more than functions that are passed to other functions as a variable to be invoked in the context of the ‘host’ function. A simple example of that would look like this:

While this isn’t asynchronous itself, it is the fundamental concept that would make it possible to do so. A general use case would look something more like this:

Note that in this example, the delay would be seemingly unnoticeable granted there were no network requests or heavy computations being carried out. Making network requests would be done in relatively the same way. It will typically look something like this:

Here, we are making a network call using jQuery and passing an anonymous function as the second parameter to run when it is complete. This makes it possible to grab information from another resource before using its value in your application. While this pattern is quick to grasp and implement, heavy use of callbacks being used in this fashion can get out of hand as a project grows. The flow of the application can become harder to follow as well as a nightmare when you begin nesting callbacks under each other in a chain of requests (often referred to as Callback Hell). Something needed to be done.

Enter the Promise API.

Promises Promises were introduced in ES6/ES2015. They represent one thing: the eventual result of an asynchronous operation. An example being:

You’ll notice that promises still take advantage of callbacks. The .then() and .catch() methods can be thought of as lifecycle hooks for the promise. When the promise is fulfilled, the callback passed to the .then() method is called. If the promise gets rejected, the same happens for the callback passed to the .catch() method. Some distinctive advantages of Promises:

  • They can be chained together, using the return value from one request in the next .then() call

  • They provide a more consistent way to handle errors

  • Can be wrapped around methods of other libraries that implement the callback interface to provide the Promise API

Async/Await The async and await keywords were added in the ES7(ES2016) spec. They provide syntactic sugar around the Promise API that allows for JavaScript code to be written as if the asynchronous calls were blocking calls. This means that any promise (or function that returns a promise) can be awaited.

Using the async keyword before defining a function, the await keyword is “exposed” inside it’s code block. Using the await keyword will “pause” execution of the following lines of code until the awaited promise completes (It does not actually pause execution though, as it only wires up the code as referenced callbacks under the hood). This can further progress the readability of our code with no sacrifice to performance.

It should be noted that this syntax isn’t widely available in browsers currently. They are available in some of the more recent versions of Chrome, Firefox, and Safari but are not entirely consistent. However, JavaScript preprocessors like Babel and TypeScript provide us with a way to transpile our code down to ES5 or ES6 so that we can use this syntax today.

In Conclusion Callbacks, while not the most convenient at times, are what makes asynchronous programming in JavaScript possible. Promises were introduced to alleviate the biggest issues callbacks brought to programmers who used them. They provide lifecycle hooks to asynchronous tasks, better error handling, and the ability to chain asynchronous tasks together in series. The async/await syntax has further helped the way we can read and write our code to make communicating with our machines just that much easier.

Although the world of JavaScript is always rapidly changing in a constantly forward-looking culture, sometimes it helps to take a step back to see just how far we’ve come.

Happy coding!

Elegant Software Solutions

#javascript #es6 #es2015 #es7 #es2016 #es5

62 views

Alpharetta, GA | meetus@essrocks.io | 855-449-4649