Async and Await in JavaScript

async and await are keywords introduced in ECMAScript 2017 (ES8) that provide syntactic sugar for working with asynchronous code, specifically for handling promises. They make asynchronous code look and behave more like synchronous code, which can make it easier to read and maintain. Here’s how async functions and await expressions work:

async Functions:

An async function is a function that operates asynchronously via the event loop, and always returns a promise. Inside an async function, you can use the await keyword to pause the execution of the function until a promise is settled (either fulfilled or rejected), and then resume the function’s execution.

async function fetchData() {
  // Asynchronously fetch data from a server
  let data = await fetchDataFromServer();
  console.log('Data received:', data);
}

fetchData();

await Expressions:

The await keyword can only be used inside an async function. It pauses the execution of the async function until the promise is settled (either fulfilled or rejected), and then resumes the function’s execution with the resolved value. If the promise is rejected, it throws an error that can be caught using a try...catch block.

async function fetchData() {
  try {
    let data = await fetchDataFromServer(); // Wait for the promise to settle
    console.log('Data received:', data);
  } catch (error) {
    console.error('Error:', error);
  }
}

Error Handling:

You can handle errors in async functions using try...catch blocks, just like synchronous code. If an error occurs inside an async function and is thrown from an await expression, the promise returned by the async function will be rejected with the thrown error.

async function fetchData() {
  try {
    let data = await fetchDataFromServer();
    console.log('Data received:', data);
  } catch (error) {
    console.error('Error:', error);
  }
}

Parallel Execution:

You can use await with multiple promises in parallel to wait for all of them to settle. By using Promise.all() with await, you can await an array of promises, and the async function will wait until all promises are settled.

async function fetchDataParallel() {
  let [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
  console.log('Data 1:', data1);
  console.log('Data 2:', data2);
}

async functions and await expressions provide a more concise and readable way to work with asynchronous code, making it easier to write and understand complex asynchronous workflows. They are widely used in modern JavaScript for handling asynchronous operations, such as fetching data from servers, making API calls, and performing I/O operations.