Saturday, 16 February 2019

JavaScript: async, await keyword


‘async’ and ‘await’ keywords are used to work with promises in clean and comfortable way.

Async functions
If you define a function using async keyword, then that function always returns a promise.

asyncDemo.js
async function f() {
  return "Hello Async";
}

f().then(console.log);

$ node asyncDemo.js
Hello Async

As you see the function f(), even though f() function actually returns a non-promise value, “async” keyword make sure that Javascript to automatically wrap that value in a resolved promise.

With async keyword, above code is interpreted like below.

async function f() {
  return Promise.resolve("Hello Async");
}

f().then(console.log);

await keyword
await keyword makes sure that, Program waits until that promise done and returns its result.

‘await’ works only inside async functions.

Syntax
let result = await promise;


asyncDemo.js
async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("I am done with Execution"), 3000);
  });

  // Wait until the promise finishes
  let result = await promise;

  console.log(result);
}

f();

$ node asyncDemo.js
I am done with Execution

Using of await in non async functions throws error

asyncDemo.js
function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("I am done with Execution"), 3000);
  });

  // Wait until the promise finishes
  let result = await promise;

  console.log(result);
}

f();

$ node asyncDemo.js 
/Users/harikrishnagurram/Documents/TechnicalDocuments/NodeJS/cors/asyncDemo.js:8
  let result = await promise;
               ^^^^^

SyntaxError: await is only valid in async function
    at new Script (vm.js:79:7)
    at createScript (vm.js:251:10)
    at Object.runInThisContext (vm.js:303:10)
    at Module._compile (internal/modules/cjs/loader.js:657:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:283:19)

Error Handling
If a promise resolves successfully, then ‘await promise’ statement returns the result. But if promise returns rejection, it throws the error.


asyncDemo.js
async function f(x) {

  let promise;

  if( x % 2 === 0){

    promise = new Promise((resolve, reject) => {
      resolve("I am done with Execution");
    });

  }else{

    promise = new Promise((resolve, reject) => {
      reject("Throwing Error");
    });

  }

  // Wait until the promise finishes
  let result = await promise;

  console.log(result);
}

console.log("Calling f with odd number");
f(5);

$ node asyncDemo.js 
Calling f with odd number
(node:11859) UnhandledPromiseRejectionWarning: Throwing Error
(node:11859) 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:11859) [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.

You can handle the error scenario using try-catch statement.

asyncDemo.js
async function f(x) {

  let promise;

  if( x % 2 === 0){

    promise = new Promise((resolve, reject) => {
      resolve("I am done with Execution");
    });

  }else{

    promise = new Promise((resolve, reject) => {
      reject(new Error("Throwing Error"));
    });

  }

  // Wait until the promise finishes
  let result;

  try {
    result = await promise;
  }catch(error){
    console.log("*********************");
    console.log(error);
    console.log("*********************");
  }

  console.log(result);
}

console.log("Calling f with odd number");
f(5);

$ node asyncDemo.js 
Calling f with odd number
*********************
Error: Throwing Error
    at Promise (/Users/harikrishnagurram/Documents/TechnicalDocuments/NodeJS/cors/asyncDemo.js:15:14)
    at new Promise (<anonymous>)
    at f (/Users/harikrishnagurram/Documents/TechnicalDocuments/NodeJS/cors/asyncDemo.js:14:15)
    at Object.<anonymous> (/Users/harikrishnagurram/Documents/TechnicalDocuments/NodeJS/cors/asyncDemo.js:35:1)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
*********************
undefined

You may like
JavaScript Interview Questions
JavaScript: Convert an element to array
Explain about Generators in JavaScript
Is Float base data type in JavaScript?
JavaScript: Immediately invoked function expressions
JavaScript: for-of loop



No comments:

Post a Comment