- Lab
- Core Tech

Guided: Asynchronous JS
In the JavaScript ecosystem, asynchronous programming is essential in order to provide a good experience to users of your app or website. Running code "in the background" or in parallel can help you perform needed tasks without blocking the user interface. In this Guided Lab, you will learn all about asynchronous programming in JavaScript as you gain practical experience using callbacks, JavaScript Promises and the async/await syntax.

Path Info
Table of Contents
-
Challenge
### Introduction
In this lab you are going to learn the ins and outs of async programming in JavaScript. To put it simply, async code runs in the background so that your main application code can continue running unblocked in the foreground. Async programming is a critical subject to understand when working with JavaScript since many JavaScript applications rely on user input. If you were to perform an operation like requesting data over the network in a synchronous fashion, then your entire application would be blocked until the request completed. This would render your application completely useless during that time!
A major benefit to async programming is that it lets you perform long-running operations in the background so that your users are free to interact with your application during that time. Async programming in JavaScript can be implemented in several ways but the most important techniques include:
- Callbacks/Event Handlers
- The Promise API
- Async/Await syntax
This lab will guide you into a full understanding of async programming in JavaScript starting from the oldest async programming techniques to the most modern. First, you will gain an understanding of JavaScript event handlers and callbacks – the oldest and often the most complex way of writing async code.
From there you will dive deep into the JavaScript Promise API – a groundbreaking API that has been the cornerstone of async programming in JavaScript for quite some time. Then you’ll build on your knowledge of the Promise API by learning about modern async/await syntax in JavaScript – a simple syntax that abstracts away a lot of the complexities of the Promise API.
When you make changes to the JavaScript file, you can simply refresh the Web Browser tab to get your new code to take effect.
info> Note: The
solution
directory contains the final solution. Feel free to view the file in that directory should you get stuck! -
Challenge
### Async Programming with Callbacks
No learning journey into async JavaScript would be complete without a digression into callbacks. Callbacks are a specific type of function that are used for, you guessed it, “calling back”. To put it simply, callbacks are functions that are designed to be called when an event happens or some other form of processing is complete.
Before more modern async programming APIs became available in event-driven environments like the browser, it was necessary to use callbacks in order to tell your programs what functions to call when certain events were triggered. To this day, there are many usages of callbacks in the DOM (Document Object Model) API and in JavaScript programs in general although more modern APIs like the Promise API along with async/await syntax are becoming increasingly prevalent.
In this step, you are inheriting an application that is in desperate need of some async programming functionality. Throughout this portion of the lab, you are going to create and use callbacks to facilitate primitive, async programming. The most prevalent example of a callback in the JavaScript ecosystem is the event handler. Event handlers are functions that you assign to be called when certain events (in this case browser events) occur. Event handlers are an extremely common way of creating callbacks and thus writing asynchronous code in JavaScript but another example of callback usage has to do with the very popular and commonly used JavaScript function
setTimeout
. It is very common in JavaScript to usesetTimeout
to delay the execution of a function by a given number of milliseconds. ThesetTimeout
function works by first receiving a callback which it will execute following the number of milliseconds given to it in the second parameter. Well done! You now have a good grasp of asynchronous code in JavaScript by way of callbacks. But, as you can see, callbacks are a little clunky. The misdirection that happens in the code with callbacks makes the code hard to follow – in fact, callbacks are a great recipe for “spaghetti” code in a large application. This is because you must jump back and forth to see where your callback functions are being executed - “following the spaghetti” so to speak. There are many APIs in JavaScript (like the DOM event API) that are set to use callbacks. But one of the most predominantly asynchronous portions of JavaScript code has to do with HTTP requests. In the next step, you’ll learn how to use Promises to write asynchronous code that is easier to reason about. -
Challenge
### The JavaScript Promise API
In this step, you are going to build on your foundational knowledge of async programming in JavaScript by learning and using the JavaScript Promise API. In JavaScript, a Promise represents the eventual result of an asynchronous operation. A Promise can succeed or fail and the native Promise type provides an API which can be used to reason about these two states. Promises were introduced with the ES6 version of JavaScript so they’ve been around for a quite some time.
Promises are seen as a step above callbacks in terms of readability and maintainability. You can create a Promise with the
new
keyword like this:const myPromise = new Promise((resolve, reject) => { if (true) { resolve(true); } else { reject(); } });
Note that to create a promise, you pass it a function that accepts two parameters -
resolve
andreject
– both of which themselves are functions. Theresolve
function is used to return a value upon successful completion of the Promise. Thereject
function is used to signify an error state i.e. that the Promise failed. In the last task you created your first Promise, but how do you access the underlying value that the Promise will eventually resolve to? You can wait for your Promise to resolve and do something with the output with thethen
method that is available on Promises. You can also chain promises together using thethen
method. Thethen
method helps you capture data from Promises when things go right... but what about when something goes wrong and your Promise cannot resolve? Well that’s when the Promise goes into a “rejected” state. To capture this error state, you must use thecatch
method. Likethen
,catch
accepts a function where the first parameter is the value (often times an error) that is caught. Sometimes when working with Promises, you need to do some work irrespective of whether or not a Promise is resolved or rejected. To account for this, you can use thefinally
method on a Promise. LIkethen
andcatch
,finally
also accepts a function. Working with a single Promise is pretty straightforward, but what about when you have multiple Promises that should be resolved together? This is what the static method on the Promise objectall
is used for.Promise.all
can be called with an array of Promises – this function will execute each Promise it receives in parallel and resolve to an array of Promise responses in the same order as the original Promise array that was passed in. ThePromise.all
function returns a Promise that can be chained in the usual fashion. Another useful function that works with multiple Promises is thePromise.race
function. This function also accepts an array of Promises but it will resolve whenever the first Promise that it executes resolves. This is helpful when you have multiple asynchronous operations that you need to execute but you want the fastest operation to win out. Well done! You’ve finished this step on working with Asynchronous JavaScript using the Promise API. Promises make reasoning about asynchronous code much easier then callbacks many times. But Promises still suffer from readability and maintainability issues – particularly when you have large Promise chains with very many calls tothen
and/orcatch
. There is a better way! In the next step, you’ll work with the JavaScriptasync
/await
syntax. -
Challenge
### A Cleaner Approach with Async/Await
In the last step you learned about the ever-useful Promise API. As you may have noticed, code that uses or works with Promises can get a little verbose. But don’t worry, there is a way to use Promises in a very clean and succinct way. The key is the
async
/await
syntax. Theasync
andawait
keywords let you write asynchronous code in JavaScript in a way that reads synchronously. This makes your async code much easier to read and maintain.info> Note: The
async
andawait
keywords were introduced with ES7 – so make sure that you are using a browser or Node version that supports the ES7 JavaScript specification (or use a transpiler) if you want to use these keywords apart from this lab.It is quite simple to use
async
andawait
. There are a few rules to follow however:You mark a function
async
. This is “syntactic sugar” that tells the JavaScript runtime that this function will return a Promise.You can only use the
await
keyword within a function that is markedasync
. The exception to this is if you are working with ESM (ES6 Modules) natively as these let you use what is known as “top level await” - functionality that essentially lets you use theawait
keyword outside of anasync
function directly.info> Note: Under the hood, the
await
keyword uses something called a “generator”. The use of JavaScript generators and theyield
syntax is not often used directly, but if you’d like to learn more than I recommend that you check out the MDN docs on the subject.Often, many organizations will seek to refactor Promise-based code to
async
/await
syntax. You will explore this approach in this step. Creating an asynchronous function is very straightforward. Theasync
keyword must be used before the function definition. When using thefunction
keyword you would create an asynchronous function with the syntax:async function <function-name>
. For arrow functions it’s a bit different and looks like this:async () => {}
. You have anasync
function but there’s no point to usingasync
without its counterpart -await
. The purpose ofawait
is to provide a synchronous looking syntax for asynchronous code which is very helpful for the readability and maintainability of your codebase. It makes your code much easier to reason about. Usingawait
also ensures that any code below the use ofawait
will only execute after the asynchronous code is finished running. It is very common out in the real world to encounter Promise-based code that needs to be refactored toasync
/await
syntax so that codebases are both up to date with more modern JavaScript syntax and easier to read/maintain. -
Challenge
### Conclusion
Nicely done! You’ve made it to the end of this guided code lab on async programming in JavaScript.
In summary, you learned:
- Async programming via callbacks/event handlers and
setTimeout
- Async programming with the Promise API
- Using the
async
/await
syntax to write clean, asynchronous code
As follow on learning, I recommend that you learn about JavaScript generators as they form the basis of the
async
/await
syntax and are another more obscure form of async programming in JavaScript.From here, you can be confident when it comes to async programming with JavaScript. I recommend that you continue your journey learning JavaScript by pursuing both video courses and more guided code labs here, at PluralSight.
- Async programming via callbacks/event handlers and
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.