JS Async: async/await
Felipe Sousa

Felipe Sousa @felipesousa

About: +9 years as a Software Developer | Frontend Specialist | Tech Speaker | Lifelong Learner | Curious about Life & Tech #abitperday

Location:
Fortaleza, Brazil
Joined:
Sep 7, 2018

JS Async: async/await

Publish Date: Sep 8 '20
67 7

This post is the last of the JS Async series, 3 posts to explain and show how to work with asynchronous data in JavaScript.

You can check out the other 2 previous articles:

Today we’ll talk about async/await and see some examples of how and what we can do with it:

Async

The keyword async was implemented in ES2017. It makes it possible to create naturally asynchronous functions using the following notation:

async function myAsyncFunction() {}
Enter fullscreen mode Exit fullscreen mode

Something important and even more interesting about this implementation is that every async function returns a Promise, meaning that we can use all the interfaces we already know in the article about promises. Let's look at an example to better understand:

async function myAsyncFunction() {
  return "Hello!";
}

myAsyncFunction().then(payload => {
  console.log(payload); // Hello!
});
Enter fullscreen mode Exit fullscreen mode

The async functions use the success values as the values that will be arranged within the.then pipeline in the promise that will be returned, in case you need to export an error, it is necessary to trigger an error within the scope of execution to be sent to the .catch pipeline, let's see an example:

async function myAsyncFunctionWithError() {
  throw "something wrong happen";
}

myAsyncFunctionWithError().catch(error => {
  console.log(error); // something wrong happen
});
Enter fullscreen mode Exit fullscreen mode

Await

The use of await is restricted only within a function declared with the keyword async, basically what it does is wait for the Promise response value or convert the value into a resolved Promise.

async function myAsyncFunction() {
  const payload = await { name: "felipe", age: 22 };
  console.log(payload); // { name: 'felipe', age: 22 }
}

myAsyncFunction();
Enter fullscreen mode Exit fullscreen mode

In cases where we are not returning any value from our function, the execution call remains as normal function calls without using .then.

Catching errors with try/catch

Await always expects the success value of the promise, so we have no way to capture the error directly, to do this we have to make use of the try/catch which receives the reject value if it happens, within the promises that are being executed inside the try block:

async function myAsyncErrorFunction() {
  throw "ops, something wrong happen";
}

async function myAsyncFunction() {
  try {
    const response = await myAsyncErrorFunction();
  } catch (error) {
    console.log(error); // ops, something wrong happen
  }
}

myAsyncFunction();
Enter fullscreen mode Exit fullscreen mode

Executing this block, the error happens inside the promise myAsyncErrorFunction and is captured inside the try/catch catch block.

In summary, the joint use of the implementations makes our code extremely simple and readable, making handling asynchronous (or synchronous) data more directly and effectively.

I hope you enjoyed this series, see you later!

🔭

Comments 7 total

  • Matt Ellen-Tsivintzeli
    Matt Ellen-TsivintzeliSep 9, 2020

    Does the fact that you can use await in the global/window scope imply that the scope is an async function?

    Sorry, bit of a weird question :D

    • Felipe Sousa
      Felipe SousaSep 9, 2020

      In this case, await can only be used within functions declared with the “async” keyword, using await in global scope or outside a function with “async” triggers the following error:

      const myPromise = new Promise((resolve) => {
        resolve(payload)
      });
      
      const response = await myPromise; // SyntaxError: await is only valid in async function
      

      😁

      • Matt Ellen-Tsivintzeli
        Matt Ellen-TsivintzeliSep 9, 2020

        That's interesting. In the console (Firefox) it worked fine. I guess that's a different scope again.

        const resp = await fetch('https://dev.to');
        const text = await resp.text();
        console.log(text);
        
  • Alexey Tukalo
    Alexey TukaloSep 9, 2020

    It is actually possible to use async/await with custom classes. I have a library which does monadic error handling like Option in Scala and Rust and perfectly works with async/await. I mean Promise already have error handling capabilities. In some sense, I tried to make a lightweight version of PromiseLike object, which is not able to work with async. If anybody is interested, you are welcome to check it out on npm - npmjs.com/package/amonad

  • JWP
    JWPSep 9, 2020

    Question:

    async function myAsyncFunction() {
      const payload = await { name: "felipe", age: 22 };
      console.log(payload); // { name: 'felipe', age: 22 }
    }
    

    This example creates a closure on payload of an object that is awaited. Does JavaScript automatically resolve the promise in this case?

    RxJs has commands like [of, from] etc, which create promises compatible with Async/Await.

    • Felipe Sousa
      Felipe SousaSep 10, 2020

      Exactly, if the “awaited” process is a value or a function that return a value, automatically this is converted to a resolved promise.

Add comment