The async keyword is used to write functions that handle asynchronous actions. We wrap our asynchronous logic inside a function prepended with the async keyword.
asyncfunctionmyFunc() {// Function body here};myFunc();
If there’s nothing returned from the function, it will return a promise with a resolved value of undefined.
If there’s a non-promise value returned from the function, it will return a promise resolved to that value.
If a promise is returned from the function, it will simply return that promise
asyncfunctionfivePromise() { return5;}fivePromise().then(resolvedValue => {console.log(resolvedValue); }) // Prints 5
AWAIT
operator used inside an async function that halts the execution of a function until a given promise is no longer pending and returns the resolved value of the promise.
Review
async...await is syntactic sugar built on native JavaScript promises and generators.
We declare an async function with the keyword async.
Inside an async function we use the await operator to pause execution of our function until an asynchronous action completes and the awaited promise is no longer pending .
await returns the resolved value of the awaited promise.
We can write multiple await statements to produce code that reads like synchronous code.
We use try...catch statements within our async functions for error handling.
We should still take advantage of concurrency by writing async functions that allow asynchronous actions to happen in concurrently whenever possible.
The await keyword can only be used inside an async function. await is an operator: it returns the resolved value of a promise. Since promises resolve in an indeterminate amount of time, await halts, or pauses, the execution of our async function until a given promise is resolved.
asyncfunctionasyncFuncExample(){let resolvedValue =awaitmyPromise();console.log(resolvedValue);}asyncFuncExample(); // Prints: I am resolved now!//EXAMPLE - 1. Library .js/*this is the brainstormDinner function. It's a little silly. It returns a promise that uses a series of setTimeout() functions to simulate a time-consuming asynchronous action. It's a good example of "callback hell" or "the pyramid of doom," two ways people describe how confusing a bunch of nested callback functions can become.
*/constbrainstormDinner= () => {returnnewPromise((resolve, reject) => {console.log(`I have to decide what's for dinner...`);setTimeout(() => {console.log('Should I make salad...?');setTimeout(() => {console.log('Should I make ramen...?');setTimeout(() => {console.log('Should I make eggs...?');setTimeout(() => {console.log('Should I make chicken...?');resolve('beans'); },1000); },1000); },1000); },1000);});};module.exports= brainstormDinner;// app.jsconstbrainstormDinner=require('./library.js');// Native promise version:functionnativePromiseDinner() {brainstormDinner().then((meal) => {console.log(`I'm going to make ${meal} for dinner.`); });}// async/await version:asyncfunctionannounceDinner() {// Write your code below:let meal =awaitbrainstormDinner();console.log(`I'm going to make ${meal} for dinner.`);}announceDinner();
Comparison of ASYNC and normal syntax
// Both performs same functionsfunctionnativePromiseVersion() {returnsFirstPromise().then((firstValue) => {console.log(firstValue);returnreturnsSecondPromise(firstValue); }).then((secondValue) => {console.log(secondValue); });}//VERSUS ASYNC WAITasyncfunctionasyncAwaitVersion() {let firstValue =awaitreturnsFirstPromise();console.log(firstValue);let secondValue =awaitreturnsSecondPromise(firstValue);console.log(secondValue);}
Explanation :
We mark our function as async.
Inside our function, we create a variable firstValue assigned await returnsFirstPromise(). This means firstValue is assigned the resolved value of the awaited promise.
Next, we log firstValue to the console.
Then, we create a variable secondValue assigned to await returnsSecondPromise(firstValue). Therefore, secondValue is assigned this promise’s resolved value.
Finally, we log secondValue to the console.
Though using the async...await syntax can save us some typing, the length reduction isn’t the main point. Given the two versions of the function, the async...await version more closely resembles synchronous code, which helps developers maintain and debug their code. The async...await syntax also makes it easy to store and refer to resolved values from promises further back in our chain which is a much more difficult task with native promise syntax.
// Beans shopping to beans dinner AWAIT//Library.jsconstshopForBeans= () => {returnnewPromise((resolve, reject) => {constbeanTypes= ['kidney','fava','pinto','black','garbanzo'];setTimeout(()=>{let randomIndex =Math.floor(Math.random() *5);let beanType = beanTypes[randomIndex];console.log(`I bought ${beanType} beans because they were on sale.`);resolve(beanType); },1000)})}letsoakTheBeans= (beanType) => {returnnewPromise((resolve, reject) => {console.log('Time to soak the beans.');setTimeout(()=>{console.log(`... The ${beanType} beans are softened.`);resolve(true); },1000); });}letcookTheBeans= (isSoftened) => {returnnewPromise((resolve, reject) => {console.log('Time to cook the beans.');setTimeout(()=>{if (isSoftened) {console.log('... The beans are cooked!');resolve('\n\nDinner is served!'); } },1000); });}module.exports= {shopForBeans, soakTheBeans, cookTheBeans};//cook beans - app.jsconst {shopForBeans,soakTheBeans,cookTheBeans} =require('./library.js');// Write your code below:asyncfunctionmakeBeans() {let type =awaitshopForBeans();let isSoft =awaitsoakTheBeans(type);let dinner =awaitcookTheBeans(isSoft);console.log(dinner)}makeBeans()
try & catch for error handling
asyncfunctionusingTryCatch() {try {let resolveValue =awaitasyncFunction('thing that will fail');let secondValue =awaitsecondAsyncFunction(resolveValue); } catch (err) {// Catches any errors in the try blockconsole.log(err); }}usingTryCatch();//EXAMPLEconstcookBeanSouffle=require('./library.js');// Write your code below:asyncfunctionhostDinnerParty(){try {let x =awaitcookBeanSouffle();console.log(`${x} is served!`); } catch (error){console.log(error);console.log('Ordering a pizza!') }}hostDinnerParty();
Handling Independent Promises
let {cookBeans, steamBroccoli, cookRice, bakeChicken} =require('./library.js')// Write your code below:asyncfunctionserveDinner() {constvegetablePromise=steamBroccoli();conststarchPromise=cookRice();constproteinPromise=bakeChicken();constsidePromise=cookBeans(); console.log(`Dinner is served. We're having ${await vegetablePromise}, ${await starchPromise}, ${await proteinPromise}, and ${await sidePromise}.`);
}serveDinner();