Understanding Async and Await in JavaScript: Simplifying Asynchronous Programming


Normal Functions

function welcome() {
  return "Hello World";
}
console.log(welcome());

The provided code defines a function named welcome without any parameters.

Inside the function body, the return statement is used to specify the value that will be returned when the function is called. In this case, the string "Hello World" is returned.

The console.log() function is used to display the result of calling the welcome function. By invoking welcome() within the parentheses of console.log() , the function is executed, and its return value, which is "Hello World" , is printed to the console.

So when you run this code, you will see the output "Hello World" printed in the console.

Async in JavaScript

In JavaScript, async and await are keywords used to simplify asynchronous programming and make it more readable and concise. They were introduced in ECMAScript 2017 (ES8) as a way to work with Promises, which are objects used for managing asynchronous operations.

The async keyword is used to declare an asynchronous function. An asynchronous function is a function that implicitly returns a Promise, allowing it to use the await keyword inside its body. It allows you to write code that appears to be synchronous while actually executing asynchronously.

Example

async function welcome() {
  return "Hello World";
}
console.log(welcome());

The provided code defines an asynchronous function named welcome using the async keyword. The function body includes a return statement that returns the string "Hello World".

When the function welcome() is called, it returns a Promise that will resolve with the value "Hello World". However, in the code provided, the console.log(welcome()) statement does not directly display the resolved value because the function is asynchronous.

Instead, the Promise returned by welcome() is logged to the console. This will display something like Promise {<pending>} indicating that a Promise object is being returned, but it has not yet been resolved.

Since the function is asynchronous, it will continue executing in the background while the Promise is pending. The code will not block and wait for the Promise to resolve before moving on to the next line.

then()

In JavaScript, the then() method is used in conjunction with Promises to handle the fulfillment or rejection of a Promise and to chain asynchronous operations together.

When an asynchronous operation is performed, it returns a Promise object. The then() method is called on that Promise object and takes two optional callback functions as arguments: onFulfilled and onRejected. These callbacks are executed based on the state of the Promise.

Here's the general syntax for using then():

promise.then(onFulfilled, onRejected);

The onFulfilled callback is executed when the Promise is successfully fulfilled (resolved). It receives the resolved value as an argument. The onRejected callback is executed when the Promise is rejected, typically when an error occurs during the asynchronous operation. It receives the reason for the rejection (usually an error object) as an argument.

If you want to access the resolved value of the Promise, you can use the then() method to attach a callback function that will be executed when the Promise is fulfilled.

welcome().then((msg) => {
    console.log(msg);
})

In this case, the callback function will receive the resolved value "Hello World" as the msg parameter and log it to the console.

So, in summary, the provided code logs the Promise object returned by the welcome() function, indicating that it is pending and will eventually resolve with the value "Hello World". To access and log the resolved value, you need to use the then() method or await the Promise in an async context.

catch()

In JavaScript, the catch() method is used in conjunction with Promises to handle errors or rejections that occur during the execution of asynchronous operations. It is specifically designed to handle the rejected state of a Promise.

When an error occurs within a Promise or the Promise is explicitly rejected using the reject() function, the catch() method is used to specify a callback function that will be executed to handle the error.

Here's an example that demonstrates the usage of catch() in an async function:

async function welcome() {
  return "Hello World";
}
console.log(welcome());

welcome()
  .then((msg) => {
    console.log(msg);
  })
  .catch((err) => {
    console.error(err);
  });

The provided code demonstrates the usage of an async function and the handling of its returned Promise using then() and catch() methods.

The function welcome is declared as an asynchronous function using the async keyword. It has no parameters and includes a return statement that returns the string "Hello World".

When the welcome() function is called, it returns a Promise that will be immediately fulfilled with the value "Hello World".

The code console.log(welcome()) logs the Promise object returned by welcome() to the console. This will display something like Promise {<fulfilled>: "Hello World"}. However, since the Promise is immediately fulfilled, it doesn't need to wait for any asynchronous operation to complete.

To access the resolved value of the Promise, the code uses the then() method to attach a callback function that will be executed when the Promise is fulfilled. In this case, the callback function receives the resolved value "Hello World" as the msg parameter and logs it to the console using console.log(msg) .

In the given code, since the Promise is immediately fulfilled, the then() callback is executed synchronously after the console.log(welcome()) statement. It directly logs "Hello World" to the console.

The catch() method is also chained after then() to handle any errors that might occur during the Promise execution. However, since the Promise is immediately fulfilled and there are no asynchronous operations or rejections happening, the catch() callback will not be triggered.

In summary, the code logs the Promise object returned by welcome() to the console, then immediately logs the resolved value "Hello World" using then() . Since there are no errors or rejections, the catch() callback is not executed in this case.

Creating Comments for Blog using Async/Await Function

Creating comments for a blog using async/await functions in JavaScript involves implementing asynchronous operations to handle CRUD (Create, Read, Update, Delete) operations for comments.

Here's a general outline of how you can approach this task:

  1. Set up a data structure or a database to store the comments for your blog. This can be an array, an object, or a database collection.
  2. Define an async function, let's say blogComment, to create a new comment for the blog. This function will receive the necessary data for the comment.
  3. Within the blogComment function, you can perform any necessary validation or data processing before creating the comment.
  4. Use the await keyword to handle asynchronous operations within the function.
  5. In case of any errors during the asynchronous operations, use try and catch to handle and manage the errors gracefully. You can throw custom errors or handle specific error cases as needed.
  6. Once the comment has been successfully created, you can return a success message or the created comment itself.

Here's a simplified example that demonstrates the process:

async function getData() {
  let blogPost = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Blog Post");
    }, 2000);
  });

  let blogComment = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Comment For Blog");
    }, 5000);
  });

  console.log("Fetching Post....");
  let post = await blogPost;
  console.log("Post : ", post);
  console.log("Fetching Comment....");
  let comment = await blogComment;
  console.log("Comment : ", comment);
  return [post, comment];
}

console.log("Welcome to Blog Post");
let data = getData();
console.log(data);

data
  .then((value) => {
    console.log(value);
  })
  .catch((err) => {
    console.log(err);
  });
  

This code represents a simplified example of fetching blog post and comment data using async/await and Promises.

  1. The getData() function is defined as an async function. Inside it, two Promises are created, blogPost and blogComment, which simulate asynchronous operations that take some time to resolve.
  2. The blogPost Promise uses setTimeout to simulate a delay of 2 seconds before resolving with the value "Blog Post". Similarly, the blogComment Promise introduces a delay of 5 seconds before resolving with the value "Comment For Blog".
  3. The code then logs "Fetching Post...." to the console, indicating that the process of fetching the blog post has started.
  4. The await keyword is used to pause the execution of the getData() function until the blogPost Promise is resolved. The resolved value is assigned to the variable post.
  5. The code logs the value of the post variable, representing the fetched blog post, to the console.
  6. The code proceeds to log "Fetching Comment...." to indicate that it is now fetching the blog comment.
  7. Similarly, the await keyword is used to pause the execution until the blogComment Promise is resolved. The resolved value is assigned to the variable comment.
  8. The code logs the value of the comment variable, representing the fetched blog comment, to the console.
  9. Finally, the function returns an array [post, comment] containing both the blog post and comment.
  10. Outside the getData() function, "Welcome to Blog Post" is logged to the console.
  11. The getData() function is called and assigned to the variable data.
  12. The data variable is logged to the console. At this point, it is a pending Promise because the asynchronous operations inside getData() have not yet completed.
  13. The then() method is used to attach a callback function that will be executed when the data Promise is fulfilled. The resolved value is logged to the console.
  14. The catch() method is used to handle any errors that might occur during the Promise execution. If an error occurs, it is logged to the console.

In summary, this code demonstrates the use of async/await to handle asynchronous operations with Promises. It simulates fetching a blog post and comment using artificial delays. The data is fetched sequentially, and the code ensures that the comments are fetched only after the blog post has been fetched.

Calculating Result using Async/Await Functions

Calculating Result using Async/Await Functions in JavaScript involves performing complex calculations, including arithmetic operations and utilizing math functions, in an asynchronous manner using the async/await syntax and Promises.

The async/await syntax is a feature introduced in JavaScript to handle asynchronous code in a more sequential and synchronous-like manner. It allows you to write asynchronous operations in a more readable and structured way.

To perform calculations asynchronously, you can define an async function that encapsulates the calculation logic. Within this function, you can use await to pause the execution until the asynchronous operations are completed.

Here's a general outline of how you can approach calculating a result asynchronously using async/await:

  • Define an async function, such as getResults, to encapsulate the calculation logic.
  • Inside the function, perform the necessary calculations using arithmetic operations and math functions. You can use variables to store intermediate results.
  • If there are any asynchronous operations involved, such as fetching data from an API or performing database queries, use await to pause the execution until those operations are completed. These asynchronous operations can be wrapped in Promises.
  • Handle any errors that might occur during the asynchronous operations using try-catch blocks. This allows you to gracefully handle exceptions and provide meaningful error messages.
  • Finally, return the calculated result from the function

Here's a simplified example that demonstrates the concept:

let result = function (marks) {
  return new Promise(function (resolve, reject) {
    console.log("Calculation Result....");
    setTimeout(() => {
      let total = 0;
      let result = "Pass";
      marks.forEach((mark) => {
        total += mark;
        if (mark < 35) {
          result = "Fail";
        }
      });
      resolve({ total: total, result: result });
    }, 2000);
  });
};

/*
90-100 A
80-89 B
70-79 C
<70 D
*/

let grade = function (response) {
  return new Promise(function (resolve, reject) {
    if (response.result == "Pass") {
      let avg = response.total / 3;
      let gradeText = "Grade D";
      if (avg >= 90 && avg <= 100) {
        gradeText = "Grade A";
      } else if (avg >= 80 && avg <= 89) {
        gradeText = "Grade B";
      } else if (avg >= 70 && avg <= 79) {
        gradeText = "Grade C";
      }
      resolve(gradeText);
    } else {
      reject("No Grade");
    }
  });
};


//then
result([98, 99, 25])
  .then((value) => {
    console.log("Total  : ", value.total);
    console.log("Result : ", value.result);
    return grade(value);
  })
  .then((data) => {
    console.log(data);
  })
  .catch((err) => {
    console.error(err);
  });
  
  
  

async function getResults() {
  try {
    const value = await result([98, 99, 55]);
    console.log("Total  : ", value.total);
    console.log("Result : ", value.result);
    const gradeText = await grade(value);
    console.log(gradeText);
  } catch (err) {
    console.error(err);
  }
}

getResults();

This code demonstrates a scenario where the calculation of a student's result and grade is performed using Promises and async/await functions in JavaScript.

  1. The result function is defined, which takes an array of marks as input. It returns a Promise that performs a calculation based on the marks.
  2. Within the Promise, there is a setTimeout to simulate a delay of 2 seconds before the calculation is completed.
  3. The calculation involves iterating through the marks array, calculating the total, and determining the result as "Pass" or "Fail" based on a threshold of 35.
  4. Once the calculation is completed, the Promise is resolved with an object containing the total and result.
  5. The grade function is defined, which takes the response object from the previous step as input. It returns a Promise that calculates the grade based on the total.
  6. Within the Promise, if the result is "Pass", the average is calculated based on the total and the corresponding grade is determined.
  7. The Promise is then resolved with the grade.
  8. The code utilizes the then() method to chain the promises together. It calls the result function with a marks array and logs the total and result to the console.
  9. Then, it calls the grade function with the response and logs the grade text.
  10. If any errors occur during the promises' execution, they are caught and logged using the catch() method.
  11. The getResults async function is defined, which performs the same calculation using async/await syntax for better readability.
  12. Within the function, the result function is called with a marks array, and the total and result are logged to the console.
  13. The grade function is called with the response, and the grade text is logged.
  14. Any errors that occur during the execution are caught and logged using the try-catch block.

Overall, this code demonstrates the calculation of a student's result and grade using Promises and async/await functions. It showcases how the async/await syntax can provide a more synchronous-like flow when dealing with asynchronous operations and how Promises can be chained together for handling sequential asynchronous tasks.

List of Programs


JS Practical Questions & Answers


JS Practical Project