Async and Await Keywords in JavaScript – Definition, Meaning, & Examples
The async
and await
keywords simplify creating and managing promises in JavaScript.
What Is the async
Keyword in JavaScript?
The async
keyword turns a regular function into an asynchronous function that returns a promise object rather than a regular JavaScript data type.
Here’s an example:
Placing the async
keyword before myMomsPromise()
turns the function into an asynchronous function. Therefore, the invocation returned a promise object.
By default, an asynchronous function returns a promise object that JavaScript resolves with the function’s returned value or rejects based on the exception thrown.
In other words, the async
keyword will automatically pass an asynchronous function’s return value through the Promise.resolve()
static method.
Regular Function vs. Asynchronous Function in JavaScript
A regular function returns a regular value. For instance, the regular function below returns a regular string value.
But an async function returns a promise object. For instance, below is an asynchronous function that returns a fulfilled promise.
The async
keyword in the snippet above instructed the function to return a promise object rather than directly outputting the string value.
Here is the function expression equivalence of the above asynchronous function:
You can also write the asynchronous function as an arrow function like so:
Important Stuff to Know about Creating Promise Objects
Here are three essential facts to remember when creating promises in JavaScript.
Regular functions can create promises
A regular function can use the Promise
constructor’s static methods to create promises. For instance, the regular function below uses the Promise.resolve()
method to return a promise object.
The Promise
constructor creates promises
You can use the Promise
constructor to create promise objects.
Here’s an example:
The async
keyword is a syntactic sugar
An async
function is a syntactic sugar that simplifies the creation of promise objects. Therefore, you can still use it to create a promise chain.
Here’s an example:
So, now that we know what an async
keyword does, let’s discuss the await
keyword.
What Is the await
Keyword in JavaScript?
The await
keyword instructs a function to wait for a promise to be settled before continuing its execution.
Example of an await
Keyword in JavaScript
The await
keyword in the snippet below instructs showMomsPromise
to wait for myMomsPromise
to be settled before continuing its execution.
What Happens If You Do Not Use an await
Keyword in an Async Function?
Suppose you omit the await
keyword in your asynchronous function. In that case, JavaScript will not wait for any pending promises. Instead, it will continue executing other code while expecting the resolution of pending promises.
Here’s an example:
Omitting the await
keyword in the snippet above caused the console.log()
statement to invoke myMomsPromise
immediately—without waiting for its promise to be resolved.
Consequently, showMomsPromise()
’s invocation returned a fulfilled promise that JavaScript resolved with an undefined
value.
Build your website with Namecheap
Does an Async Function Always Return a Promise Object?
An async function will always return a promise—even if you do not return any value.
Example of an async function that does not return any value
The async function above returned a promise that JavaScript resolved with an undefined
value because we did not explicitly tell it to return any item.
Example of an async function that logs items to the console
The async function in the snippet above returned a promise with an undefined
value because we did not tell it to return any value. Instead, we only told it to log "I get a book"
to the browser’s console.
Example of an async function that returns a value
The async function above returned a promise object that JavaScript fulfilled with the function’s returned value.
So, now that you know how the async
and await
keywords work, we can discuss how to convert a then()
promise chain to an async/await code.
How to Convert a then()
Promise Code to an Async/Await Program
Consider the following code:
The snippet above used a chain of then()
methods to attach callbacks to the myMomsPromise
object. You can simplify the code by replacing the then()
blocks with async/await like so:
The snippet above used the await
keyword before each asynchronous function call rather than creating a chain of then()
blocks. Afterward, we assigned the returned promise objects to the firstPromise
, secondPromise
, thirdPromise
, and fourthPromise
variables, respectively.
To optimize your code, you can also use a hybrid of the then()
block and the async/await keywords.
Here’s an example:
The snippet above made myMomsPromise
a pure function by returning its value and using a then()
block to manage it.
Use Flexbox like a pro
How Does an Async Function’s Execution Order Work?
Consider the following MDN’s statements:
The body of an async function can be thought of as being split by zero or more await expressions.
Top-level code, up to and including the first await expression (if there is one), is run synchronously. In this way, an async function without an await expression will run synchronously.
If there is an await expression inside the function’s body, however, the async function will always complete asynchronously.
Code after each await expression can be thought of as existing in a
.then
callback. In this way a promise chain is progressively constructed with each reentrant step through the function. The return value forms the final link in the chain.— MDN
Let’s use an example to understand the above statements.
Example of How an Async Function’s Execution Order Works
Consider this snippet below:
Here’s what we did in the snippet above:
- We use a regular function (
startPromiseChecks
) to run an asynchronous function (checkMomAndDadsPromises
) - We programmed the
checkMomAndDadsPromises
asynchronous function to await two promises (myMomsPromise
andmyDadsPromise
).
When startPromiseChecks()
is running, in what order would its statements execute? Let’s find out.
startPromiseChecks
will first invoke thecheckMomAndDadsPromises
async function.checkMomAndDadsPromises
will start its execution synchronously until it reaches its firstawait
expression’s pending promise.- On getting to its first
await
expression,checkMomAndDadsPromises
will:- Log
"===Promises confirmation check started==="
and"Starting mom's promise check..."
to the browser’s console. - Wait for
myMomsPromise
’s resolution—while also yielding control back tostartPromiseChecks
(the function that invokedcheckMomAndDadsPromises
).
- Log
- While awaiting
myMomsPromise
’s settlement,startPromiseChecks
—which now has the control—will continue executing its code. - After a while (
5000
milliseconds), whenmyMomsPromise
gets settled,checkMomAndDadsPromises
will regain control. Therefore, it will:- Assign the first
await
expression’s resolution tomomsPromiseResponse
. - Log the
momsPromiseResponse
’s value to the browser’s console. - Evaluates its second
await
expression - Log
"Starting dad's promise check..."
to the browser’s console. - Wait for
myDadsPromise
’s resolution—while also yielding control back tostartPromiseChecks
(the function that invokedcheckMomAndDadsPromises
).
- Assign the first
- While awaiting
myDadsPromise
’s settlement,startPromiseChecks
—which now has the control—will continue executing its code. - After a while (
1000
milliseconds), whenmyDadsPromise
gets settled,checkMomAndDadsPromises
will regain control. Therefore, it will:- Assign the second
await
expression’s resolution todadsPromiseResponse
. - Log the
dadsPromiseResponse
’s value to the browser’s console.
- Assign the second
After logging dadsPromiseResponse
’s value to the browser’s console, if any return
expression exists inside the checkMomAndDadsPromises
function, the computer will yield control to the expression. However, none exist in our case, so startPromiseChecks()
’s invocation output will look like this: