search
HomeWeb Front-endCSS TutorialUnderstanding Async Await

Understanding Async Await

When writing code for the web, eventually you’ll need to do some process that might take a few moments to complete. JavaScript can’t really multitask, so we’ll need a way to handle those long-running processes.

Async/Await is a way to handle this type of time-based sequencing. It’s especially great for when you need to make some sort of network request and then work with the resulting data. Let’s dig in!

Promise? Promise.

Async/Await is a type of Promise. Promises in JavaScript are objects that can have multiple states (kind of like the real-life ones ☺️). Promises do this because sometimes what we ask for isn’t available immediately, and we’ll need to be able to detect what state it is in.

Consider someone asks you to promise to do something for them, like help them move. There is the initial state, where they have asked. But you haven’t fulfilled your promise to them until you show up and help them move. If you cancel your plans, you rejected the promise.

Similarly, the three possible states for a promise in JavaScript are:

  • pending: when you first call a promise and it’s unknown what it will return.
  • fulfilled: meaning that the operation completed successfully
  • rejected: the operation failed

Here’s an example of a promise in these states:

Here is the fulfilled state. We store a promise called getSomeTacos, passing in the resolve and reject parameters. We tell the promise it is resolved, and that allows us to then console log two more times.

const getSomeTacos = new Promise((resolve, reject) => {
  console.log("Initial state: Excuse me can I have some tacos");

  resolve();
})
  .then(() => {
    console.log("Order some tacos");
  })
  .then(() => {
    console.log("Here are your tacos");
  })
  .catch(err => {
    console.error("Nope! No tacos for you.");
  });
> Initial state: Excuse me can I have some tacos
> Order some tacos
> Here are your tacos

If we choose the rejected state, we’ll do the same function but reject it this time. Now what will be printed to the console is the Initial State and the catch error:

const getSomeTacos = new Promise((resolve, reject) => {
  console.log("Initial state: Excuse me can I have some tacos");

  reject();
})
  .then(() => {
    console.log("Order some tacos");
  })
  .then(() => {
    console.log("Here are your tacos");
  })
  .catch(err => {
    console.error("Nope! No tacos for you.");
  });
> Initial state: Excuse me can I have some tacos
> Nope! No tacos for you.

And when we select the pending state, we’ll simply console.log what we stored, getSomeTacos. This will print out a pending state because that’s the state the promise is in when we logged it!

console.log(getSomeTacos)
> Initial state: Excuse me can I have some 🌮s
> Promise {<pending>}
> Order some 🌮s
> Here are your 🌮s</pending>

What then?

But here’s a part that was confusing to me at first. To get a value out of a promise, you have to use .then() or something that returns the resolution of your promise. This makes sense if you think about it, because you need to capture what it will eventually be — rather than what it initially is — because it will be in that pending state initially. That’s why we saw it print out Promise {} when we logged the promise above. Nothing had resolved yet at that point in the execution.

Async/Await is really syntactic sugar on top of those promises you just saw. Here’s a small example of how I might use it along with a promise to schedule multiple executions.

async function tacos() {
  return await Promise.resolve("Now and then I get to eat delicious tacos!")
};

tacos().then(console.log)

Or a more in-depth example:

// this is the function we want to schedule. it's a promise.
const addOne = (x) => {
  return new Promise(resolve => {
    setTimeout(() => { 
      console.log(`I added one! Now it's ${x   1}.`)
      resolve()
    }, 2000);
  })
}

// we will immediately log the first one, 
// then the addOne promise will run, taking 2 seconds
// then the final console.log will fire
async function addAsync() {
  console.log('I have 10')
  await addOne(10)
  console.log(`Now I'm done!`)
}

addAsync()
> I have 10
> I added one! Now it's 11.
> Now I'm done!

One thing (a)waits for another

One common use of Async/Await is to use it to chain multiple asynchronous calls. Here, we’ll fetch some JSON that we’ll use to pass into our next fetch call to figure out what type of thing we want to fetch from the second API. In our case, we want to access some programming jokes, but we first need to find out from a different API what type of quote we want.

The first JSON file looks like this- we want the type of quote to be random:

{
  "type": "random"
}

The second API will return something that looks like this, given that random query parameter we just got:

{
  "_id":"5a933f6f8e7b510004cba4c2",
  "en":"For all its power, the computer is a harsh taskmaster. Its programs must be correct, and what we wish to say must be said accurately in every detail.",
  "author":"Alan Perlis",
  "id":"5a933f6f8e7b510004cba4c2"
}

We call the async function then let it wait to go retrieve the first .json file before it fetches data from the API. Once that happens, we can do something with that response, like add it to our page.

async function getQuote() {
  // get the type of quote from one fetch call, everything else waits for this to finish
  let quoteTypeResponse = await fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`)
  let quoteType = await quoteTypeResponse.json()

    // use what we got from the first call in the second call to an API, everything else waits for this to finish
  let quoteResponse = await fetch("https://programming-quotes-api.herokuapp.com/quotes/"   quoteType.type)
  let quote = await quoteResponse.json()

  // finish up
  console.log('done')
}

We can even simplify this using template literals and arrow functions:

async function getQuote() {
  // get the type of quote from one fetch call, everything else waits for this to finish
  let quoteType = await fetch(`quotes.json`).then(res => res.json())

    // use what we got from the first call in the second call to an API, everything else waits for this to finish
  let quote = await fetch(`programming-quotes.com/${quoteType.type}`).then(res => res.json())

  // finish up
  console.log('done')
}

getQuote()

Here is an animated explanation of this process.

Try, Catch, Finally

Eventually we’ll want to add error states to this process. We have handy try, catch, and finally blocks for this.

try {
  // I’ll try to execute some code for you
}
catch(error) {
  // I’ll handle any errors in that process
} 
finally {
  // I’ll fire either way
}

Let’s restructure the code above to use this syntax and catch any errors.

async function getQuote() {
  try {
    // get the type of quote from one fetch call, everything else waits for this to finish
    let quoteType = await fetch(`quotes.json`).then(res => res.json())

      // use what we got from the first call in the second call to an API, everything else waits for this to finish
    let quote = await fetch(`programming-quotes.com/${quoteType.type}`).then(res => res.json())

    // finish up
    console.log('done')
  }

  catch(error) {
    console.warn(`We have an error here: ${error}`)
  }
}

getQuote()

We didn’t use finally here because we don’t always need it. It is a block that will always fire whether it is successful or fails. Consider using finally any time you’re duplicating things in both try and catch. I usually use this for some cleanup. I wrote an article about this, if you’re curious to know more.

You might eventually want more sophisticated error handling, such as a way to cancel an async function. There is, unfortunately, no way to do this natively, but thankfully, Kyle Simpson created a library called CAF that can help.

Further Reading

It’s common for explanations of Async/Await to begin with callbacks, then promises, and use those explanations to frame Async/Await. Since Async/Await is well-supported these days, we didn’t walk through all of these steps. It’s still pretty good background, especially if you need to maintain older codebases. Here are some of my favorite resources out there:

  • Async JavaScript: From Callbacks, to Promises, to Async/Await (Tyler McGinnis)
  • Asynchronous JavaScript with async/await (Marius Schulz)
  • Mastering Async JavaScript (James K. Nelson)

The above is the detailed content of Understanding Async Await. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Simulating Mouse MovementSimulating Mouse MovementApr 22, 2025 am 11:45 AM

If you've ever had to display an interactive animation during a live talk or a class, then you may know that it's not always easy to interact with your slides

Powering Search With Astro Actions and Fuse.jsPowering Search With Astro Actions and Fuse.jsApr 22, 2025 am 11:41 AM

With Astro, we can generate most of our site during our build, but have a small bit of server-side code that can handle search functionality using something like Fuse.js. In this demo, we’ll use Fuse to search through a set of personal “bookmarks” th

Undefined: The Third Boolean ValueUndefined: The Third Boolean ValueApr 22, 2025 am 11:38 AM

I wanted to implement a notification message in one of my projects, similar to what you’d see in Google Docs while a document is saving. In other words, a

In Defense of the Ternary StatementIn Defense of the Ternary StatementApr 22, 2025 am 11:25 AM

Some months ago I was on Hacker News (as one does) and I ran across a (now deleted) article about not using if statements. If you’re new to this idea (like I

Using the Web Speech API for Multilingual TranslationsUsing the Web Speech API for Multilingual TranslationsApr 22, 2025 am 11:23 AM

Since the early days of science fiction, we have fantasized about machines that talk to us. Today it is commonplace. Even so, the technology for making

Jetpack Gutenberg BlocksJetpack Gutenberg BlocksApr 22, 2025 am 11:20 AM

I remember when Gutenberg was released into core, because I was at WordCamp US that day. A number of months have gone by now, so I imagine more and more of us

Creating a Reusable Pagination Component in VueCreating a Reusable Pagination Component in VueApr 22, 2025 am 11:17 AM

The idea behind most of web applications is to fetch data from the database and present it to the user in the best possible way. When we deal with data there

Using 'box shadows' and clip-path togetherUsing 'box shadows' and clip-path togetherApr 22, 2025 am 11:13 AM

Let's do a little step-by-step of a situation where you can't quite do what seems to make sense, but you can still get it done with CSS trickery. In this

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Atom editor mac version download

Atom editor mac version download

The most popular open source editor