🚀 Introduction to Promises, Async and Await in Javascript for web developers
Tags: javascript, beginners, api, webdev
Published: 2023-08-13 12:58:37

In the fast-paced world of web development, creating applications that are both interactive and responsive is a must!

One of the key tools that helps accomplish this is ***asynchronous programming.*** This powerful technique allows tasks to be executed independently, without the need to block the main execution thread. And when it comes to web development, JavaScript is definitely the MVP! With its wide array of tools, JavaScript makes handling asynchronous operations a breeze. So, let's dive into the exciting world of JavaScript Promises, `await`, and `async` – three game-changing tools that make asynchronous programming more manageable and elegant. Let's go!

## Table of Contents
&nbsp;1. [Understanding Asynchronous Programming](#understanding-asynchronous-programming)
&nbsp;2. [Promises: Managing Asynchronous Operations](#promises-managing-asynchronous-operations)
&nbsp;3. [async and await: A Syntactic Sweetener](#async-and-await-a-syntactic-sweetener)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1. [The async Keyword](#the-raw-async-endraw-keyword)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2. [The await Keyword](#the-await-keyword)
&nbsp;4. [Error Handling with Promises, async, and await](#error-handling-with-promises-async-and-await)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3. [Promises](#promises)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4. [async/await](#-raw-async-endraw-raw-await-endraw-)
&nbsp;5. [Chaining Asynchronous Operations](#chaining-asynchronous-operations)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.5. [Promises](#promises)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.6. [async/await](#-raw-async-endraw-raw-await-endraw-)
&nbsp;6. [Conclusion](#conclusion)

## Understanding Asynchronous Programming

To understand `Promises`, `async` and `await`, it's important first to understand asynchronous programming. In JavaScript, tasks are processed one after another by default. However, some tasks, like reading files, making network requests, or processing large amounts of data, can take a long time to complete. If these tasks block the main thread, it can make the application unresponsive, which is not good. Asynchronous programming allows tasks to run at the same time, so the main thread can continue to work on other tasks while waiting for the time-consuming one to finish. This is done by using [callback functions](https://www.w3schools.com/js/js_callback.asp), `Promises`, and, more recently, the `await` and `async` keywords. These techniques help developers write code that is efficient and responsive, making the most of available resources.

## Promises: Managing Asynchronous Operations

In ECMAScript 6 (ES6), the concept of `Promises` was introduced to make asynchronous programming easier and to tackle scenarios where multiple asynchronous tasks require coordination. A Promise is an object that represents a value that may be accessible presently, in the future, or not at all. To illustrate, consider a basic example of a Promise that mimics retrieving data from a server.

```javascript
const fetchData = new Promise((resolve, reject) => {
  setTimeout(() => {
    const data = { id: 1, name: 'John Doe' };
    resolve(data); // Resolving the Promise with the fetched data
  }, 2000);
});

fetchData.then(result => {
  console.log(result); // Output: { id: 1, name: 'John Doe' }
});
```

In this example, the `fetchData` `Promise` represents an asynchronous operation that will be resolved with the fetched data after a 2-second delay. The `.`[`then`](https://www.w3schools.com/js/js_promise.asp)`()` method is used to handle the resolved value.

Promises have three states: `pending`, `fulfilled`, and `rejected`. The `resolve` function transitions the Promise to the `fulfilled` state with the provided value, while the `reject` function transitions it to the `rejected` state with an error.

## async and await: A Syntactic Sweetener


Although `Promises` offer an improvement over callback hell in asynchronous programming, things can still get pretty complicated when multiple asynchronous operations are involved. This often leads to complex and hard-to-read code, which can be a real headache for developers. However, the introduction of the `async` and `await` keywords in **ES8** have provided a more synchronous-looking syntax for handling asynchronous code. This has helped to simplify the process and make it more intuitive for developers to work with. With these new features, developers can now write cleaner, more readable code that is easier to debug and maintain.

### The `async` Keyword

The `async` keyword is a special identifier used in JavaScript to declare an asynchronous function. This type of function always returns a `Promise`, which is a special object used for handling asynchronous operations in JavaScript. The benefit of using the `async` keyword is that it enables you to write **asynchronous code** that appears similar to **[synchronous code](https://www.scaler.com/topics/synchronous-and-asynchronous-javascript/#:~:text=As%20its%20base%20JavaScript%20language,instruction%20to%20complete%20its%20execution.)**, making it easier to follow and maintain. Essentially, an `async` function allows you to avoid callback hell, which is a common issue that arises when working with asynchronous code. By using the `async/await` syntax, you can write asynchronous code in a more concise and readable way.

```javascript
async function fetchDataAsync() {
  return { id: 1, name: 'Jane Smith' };
}

fetchDataAsync().then(result => {
  console.log(result); // Output: { id: 1, name: 'Jane Smith' }
});
```

In this example, `fetchDataAsync` is an asynchronous function that directly returns an object. Even though it looks like synchronous code, calling `fetchDataAsync()` still returns a Promise.

### The await Keyword

When dealing with `async` functions, developers utilize the keyword `await` within a function in order to pause its execution until the `Promise` has been resolved. This technique provides a more streamlined and understandable method for managing Promises. To further clarify, let's examine an example implementation of the await keyword in action.

```javascript
async function fetchAndProcessData() {
  const data = await fetchDataAsync();
  console.log(data); // Output: { id: 1, name: 'Jane Smith' }
}
fetchAndProcessData();
```

In this example, `await fetchDataAsync()` pauses the execution of `fetchAndProcessData` until the Promise returned by `fetchDataAsync` is resolved. This makes the code read as if it's performing synchronous operations, even though it's still asynchronous behind the scenes.

## Error Handling with Promises, async, and await

Error handling is a critical aspect of asynchronous programming. Both Promises and `async`/`await` offer mechanisms for dealing with errors.

### Promises

```javascript
fetchData.catch(error => {
  console.error('Error:', error);
});
```

### `async`/`await`

```javascript
async function fetchDataAndHandleError() {
  try {
    const data = await fetchDataAsync();
    console.log(data);
  } catch (error) {
    console.error('Error:', error);
  }
}
```

## Chaining Asynchronous Operations

![promises, async and await](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2veghihky87pb9x7qlw6.png)

Both Promises and `async`/`await` allow chaining multiple asynchronous operations.

### Promises

```javascript
fetchData.then(result => {
  return performAdditionalAsyncOperation(result);
}).then(finalResult => {
  console.log(finalResult);
}).catch(error => {
  console.error('Error:', error);
});
```

### `async`/`await`

```javascript
async function fetchAndProcess() {
  try {
    const data = await fetchDataAsync();
    const processedData = await performAdditionalAsyncOperation(data);
    console.log(processedData);
  } catch (error) {
    console.error('Error:', error);
  }
}
```

## Conclusion

In contemporary web development, asynchronous programming is a crucial skill. Fortunately, JavaScript offers a range of tools that can make it more manageable. These tools include `Promises`, `async`/`await`, and `callbacks`, all of which provide different levels of abstraction for handling asynchronous operations. When utilized effectively, they allow developers to write cleaner and more readable code.

`Promises` are a particularly useful tool for managing asynchronous tasks and handling potential errors. They provide a structured way to manage asynchronous operations, making it easier to handle multiple tasks simultaneously. Additionally, they allow developers to handle errors in a more structured way, which can reduce the likelihood of bugs and improve code quality.

Meanwhile, `async/await` and `callbacks` offer a more synchronous-like syntax, making code more readable and easier to follow. By using these tools, developers can write code that is easier to understand and maintain. This can lead to more responsive and user-friendly applications that take full advantage of JavaScript's asynchronous capabilities.

Overall, understanding and effectively using these tools is essential for modern web development. By doing so, developers can create more reliable, efficient, and user-friendly applications that meet the needs of their users.

References

[Image: promises, async and await](https://www.google.com/url?sa=i&url=https%3A%2F%2Flevelup.gitconnected.com%2Fasync-await-vs-promises-4fe98d11038f&psig=AOvVaw1iC2AlL46Q32c2wmC3UYGa&ust=1692016408266000&source=images&cd=vfe&opi=89978449&ved=0CBMQjhxqFwoTCMC6vc_S2YADFQAAAAAdAAAAABAE)

[Cover Image](https://www.google.com/url?sa=i&url=https%3A%2F%2Fblog.devgenius.io%2Fhow-do-differences-in-promise-chains-and-async-await-affect-your-code-logic-b85aeb566ebb&psig=AOvVaw1iC2AlL46Q32c2wmC3UYGa&ust=1692016408266000&source=images&cd=vfe&opi=89978449&ved=0CBMQjhxqFwoTCMC6vc_S2YADFQAAAAAdAAAAABAI)