AppDividend
Latest Code Tutorials

Javascript async-await Example | ES 7 async-await

1

Javascript async-await feature is used to deal with asynchronous code in javascript.  The async-await is a just new technique to write async code in a sync function manner.  You can write it as a simple synchronous function. That makes it very popular and understandable. Node.js is now supporting async-await out of the box.

Async-await is a new way to write asynchronous code. Previous options for asynchronous code are callbacks and promisesAsync/await built on top of promises. It cannot be used with plain callbacks or node callbacks.

Prerequisites

You can read the following tutorials if you do not know anything about Javascript callbacks and promises.

Promises In ES6

Callback in Javascript

Introduction

ES 2017 introduced Asynchronous functions.

Async functions are necessarily a cleaner way to work with asynchronous code in JavaScript.

If we want to understand precisely what async-await is and how they work, we first need to understand Promises.

Javascript Promise

A promise is an object that may produce a single value sometime in the future: either a resolved value or a reason that it’s not resolved (e.g., a network error occurred).

A promise may be in one of 3 possible states: fulfilled, rejected, or pending.

Promise users can attach callbacks to handle the fulfilled value or the reason for rejection.

Promises are eager, meaning that a promise will start doing whatever task you give it as soon as the promise constructor is invoked. 

Now, let’s understand the async functions in js.

Async functions in Javascript

The word “async” before a function means one simple thing: a function always returns the promise. Other values are wrapped in a resolved promise automatically.

// app.js

async function mando() {
  return 'baby yoda';
}
mando().then(data => {
  console.log(data)
})

Output

➜  es git:(master) ✗ node app
baby yoda
➜  es git:(master) ✗

So, the async function ensures that the function returns a promise.

We need to resolve the promise, and then we will get the value.

Now, let’s understand what is await in Javascript.

Await in Javascript

The keyword await JavaScript to wait until that promise settles and returns its result.

// app.js

async function mando() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("Baby Yoda"), 1000)
  });
  let result = await promise;
  console.log(result);
}

mando();

 Output

➜  es git:(master) ✗ node app
Baby Yoda
➜  es git:(master) ✗

The mando() function returns the promise and await keyword makes javascript wait until 1 second, and after that, it will return the value, which is “Baby Yoda”.

The function execution “pauses” because of setTimeOut() and resumes when the promise settles, with the result becoming its result. So the code above shows “Baby Yoda” in one second.

Let’s understand underneath what happened: Javascript await JavaScript wait until the promise settles, and then go on with the result. That doesn’t cost any CPU resources because the engine can do other jobs meanwhile: execute other scripts, handle events, etc.

It’s just a more elegant syntax of getting the promised result than a promise.then(), more comfortable to read and write.

If we try to use await in non-async function, there would be a syntax error:

function mando() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("Baby Yoda"), 1000)
  });
  let result = await promise;
  console.log(result);
}

mando();

 Output

➜  es git:(master) ✗ node app
/Users/krunal/Desktop/code/node-examples/es/app.js:5
  let result = await promise;
               ^^^^^

SyntaxError: await is only valid in async function
    at wrapSafe (internal/modules/cjs/loader.js:1050:16)
    at Module._compile (internal/modules/cjs/loader.js:1098:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:983:32)
    at Function.Module._load (internal/modules/cjs/loader.js:891:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
➜  es git:(master) ✗

 We will get the syntax error because we can not use await in plain javascript function.

The await won’t work in the top-level code. See the following code.

// app.js

let response = await fetch('https://api.github.com/users/KrunalLathiya')
let user = await response.json()
console.log(user)

 Output

➜  es git:(master) ✗ node app
/Users/krunal/Desktop/code/node-examples/es/app.js:1
let response = await fetch('https://api.github.com/users/KrunalLathiya')
               ^^^^^

SyntaxError: await is only valid in async function
    at wrapSafe (internal/modules/cjs/loader.js:1050:16)
    at Module._compile (internal/modules/cjs/loader.js:1098:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:983:32)
    at Function.Module._load (internal/modules/cjs/loader.js:891:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
➜  es git:(master) ✗

 You need to wrap it into an anonymous async function, like the following code.

// app.js

const fetch = require('node-fetch')
const dev = process.env.NODE_ENV !== 'production';

(async () => {
  let response = await fetch('https://api.github.com/users/KrunalLathiya')
  let user = await response.json()
  console.log(user.login)
})()

 You need to install the node-fetch library from NPM to run the above program.

Output

➜  es git:(master) ✗ node app
KrunalLathiya
➜  es git:(master) ✗

Now, let’s understand JS async-await.

Javascript async-await Example

The async-wait is non-blocking.

Javascript async-await was created to simplify the process of working with and writing chained promises.

Our function has the keyword async before it.

The await keyword can only be used inside functions defined with async

Any async function returns a promise implicitly, and the resolution value of the promise will be whatever you return from the function.

// server.js

async function Crypto() {
   return 10000;
 }
 
Crypto().then(BTC => {
   console.log(BTC)
});

In the above example, It is quite clear that async function will always return a promise, and if you have noted here that I have not used await yet.

Await function will always work inside the Async function. If you write await in the normal function then, it will give us an error.

The keyword await JavaScript to wait until that promise settles and returns its result. So it will pause until we can get our promise resolve and returns the resolved value.

Class Methods as async

A class method can also be async, just put async before it.

// server.js

class Crypto {
   async getCoin() {
     return await Promise.resolve(10000);
   }
 }
 
 new Crypto()
   .getCoin()
   .then(BTC => {console.log(BTC)});

Error handling

If a promise usually resolves, then await promise returns the result. But in case of a rejection, it throws the error, just as if there were a throw statement at that line.

async function mando() {
  await Promise.reject(new Error("Ohh!! Something went wrong"));
}
mando()

 Output

➜  es git:(master) ✗ node app
(node:58165) UnhandledPromiseRejectionWarning: Error: Ohh!! Something went wrong
    at mando (/Users/krunal/Desktop/code/node-examples/es/app.js:2:24)
    at Object.<anonymous> (/Users/krunal/Desktop/code/node-examples/es/app.js:4:1)
    at Module._compile (internal/modules/cjs/loader.js:1128:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:983:32)
    at Function.Module._load (internal/modules/cjs/loader.js:891:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
(node:58165) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:58165) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
➜  es git:(master) ✗

 We can catch that error using the try…catch, the same way as a regular throw.

// server.js

const fetch = require('node-fetch');

async function Crypto() {

   try {
     let response = await fetch('http://gibberissssh.com');
   } catch(err) {
     console.log(err);
   }
 }
 
 Crypto();

Switching from Promises to Async/Await.

We can use async/await in the following way.

function doubleAfter2Seconds(x) {
   return new Promise(resolve => {
     setTimeout(() => {
       resolve(x * 5);
     }, 2000);
   });
 }
 
 async function addAsync(x) {
   const a = await doubleAfter2Seconds(10);
   const b = await doubleAfter2Seconds(20);
   const c = await doubleAfter2Seconds(30);
   return x + a + b + c;
 }
 
 
 addAsync(100).then((sum) => {
   console.log(sum); //400
 });

In the above code, first, we have written the doubleAfter2Seconds() this function, which returns a promise. Then we have called this function in the async function and waiting until it resolves.

Then it will return a sum of that function. Finally!! You have just created an asynchronous function in JavaScript.

Conclusion

The async keyword before a function has two effects:

  1. Makes it always return a promise.
  2. Allows using await in it.

The await keyword before a promise makes JavaScript wait until that promise settles, and then:

If it’s an error, the exception is generated, the same as if throw error were called at that very place.
Otherwise, it returns the result.

Together they provide an excellent framework to write asynchronous code that is easy both to read and write.

With async-await we rarely need to write promise.then/catch, But we still shouldn’t forget that they are based on promises, because sometimes (e.g., in the outermost scope) we have to use these methods. Also Promise.all is a nice thing to wait for many tasks simultaneously.

Finally, Javascript async-wait Example is over.

See also

Node async-await example

Javascript Promise.resolve()

Javascript Promise.reject()

Javascript Promise.all()

Javascript Promise.race()

1 Comment
  1. Vishnu says

    Hi,
    too much ads in your site.
    its very difficult to concentrate.

    regards
    Vishnu

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.