Skip to content

Commit

Permalink
fix: reverse order for callback hell, promises and async/await
Browse files Browse the repository at this point in the history
  • Loading branch information
paolapog committed Jan 9, 2024
1 parent a62203c commit 7a231b1
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 47 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Note: these are knowledge "__bites__", and I expect there to be a curiosity to _
### JS
- [Ajax vs JSOP](./javascript/ajax-jsonp.md)
- [Anonymous vs named vs arrow functions](./javascript/anonymous-named-arrow-functions.md)
- [Async/await, promises and callback hell](./javascript/async-await-promises.md)
- [Callback hell, Promises and Async/Await](./javascript/async-await-promises.md)
- [Bundler vs transpiler](./javascript/bundler-vs-transpiler.md)
- [Call vs apply vs bind methods](./javascript/call-apply-bind.md)
- [Closure](./javascript/closure.md)
Expand Down
93 changes: 47 additions & 46 deletions javascript/async-await-promises.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,32 @@
## Async/Await
## Callback Hell

Async/Await is a modern way to handle asynchronous operations in JavaScript. It is built on top of Promises and allows you to write asynchronous code in a more synchronous manner.
Callback hell, also known as the Pyramid of Doom, refers to a situation where callbacks are nested within callbacks, leading to code that is difficult to read and understand. This often happens when dealing with multiple asynchronous operations that need to be performed in a specific order.

```javascript
async function fetchUser() {
const response = await fetch('https://api.github.com/users/octocat');
const data = await response.json();
console.log(data);
}
Here's an example of callback hell:

fetchUser();
```javascript
getData(function(a) {
getMoreData(a, function(b) {
getMoreData(b, function(c) {
getMoreData(c, function(d) {
// Do something with 'd'
});
});
});
});
```

In this example, `fetchUser` is an async function. Inside this function, the `await` keyword is used to pause the execution of the function until the Promise returned by `fetch` is resolved. Then, it does the same for the `response.json()` call. If any of these Promises are rejected, an error will be thrown.
In this example, each `getMoreData` function takes some data as input, performs an asynchronous operation, and then calls a callback function with the result. The callbacks are nested within each other because each operation depends on the result of the previous operation.

This makes the code much easier to read and write than using Promises directly, especially when dealing with multiple asynchronous operations in a row.
This pattern can lead to code that is hard to read and understand, especially as the number of nested callbacks increases. It can also make error handling difficult, as each callback would need to handle errors individually.

```javascript
async function fetchUser() {
try {
const response = await fetch('https://api.github.com/users/octocat');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('An error occurred: ' + error.message);
}
}
To mitigate callback hell, you can:

fetchUser();
```
1. **Modularize**: Break down your code into smaller, reusable functions.
2. **Use Promises or Async/Await**: These features of JavaScript allow you to write asynchronous code that is easier to read and understand.
3. **Use a flow control library**: Libraries like async.js provide functions for managing and organizing asynchronous code.

A try/catch block is used to handle any errors that might occur during the fetch operation or while parsing the JSON. If an error is thrown inside the try block, execution will immediately jump to the catch block, where the error can be handled. This is similar to how error handling works in synchronous code, making it easier to reason about.
Remember, the key to avoiding callback hell is to keep your code structured and manageable, regardless of the specific techniques you use.

## Promises

Expand Down Expand Up @@ -68,35 +61,43 @@ If the operation fails, you call `reject` with the reason for the failure. This

Promises can be chained together to perform a series of asynchronous operations in a specific order. Each `then` returns a new Promise, allowing you to chain them together. If any Promise in the chain is rejected, the `catch` at the end will be triggered.

## Callback Hell

Callback hell, also known as the Pyramid of Doom, refers to a situation where callbacks are nested within callbacks, leading to code that is difficult to read and understand. This often happens when dealing with multiple asynchronous operations that need to be performed in a specific order.
## Async/Await

Here's an example of callback hell:
Async/Await is a modern way to handle asynchronous operations in JavaScript. It is built on top of Promises and allows you to write asynchronous code in a more synchronous manner.

```javascript
getData(function(a) {
getMoreData(a, function(b) {
getMoreData(b, function(c) {
getMoreData(c, function(d) {
// Do something with 'd'
});
});
});
});
async function fetchUser() {
const response = await fetch('https://api.github.com/users/octocat');
const data = await response.json();
console.log(data);
}

fetchUser();
```

In this example, each `getMoreData` function takes some data as input, performs an asynchronous operation, and then calls a callback function with the result. The callbacks are nested within each other because each operation depends on the result of the previous operation.
In this example, `fetchUser` is an async function. Inside this function, the `await` keyword is used to pause the execution of the function until the Promise returned by `fetch` is resolved. Then, it does the same for the `response.json()` call. If any of these Promises are rejected, an error will be thrown.

This pattern can lead to code that is hard to read and understand, especially as the number of nested callbacks increases. It can also make error handling difficult, as each callback would need to handle errors individually.
This makes the code much easier to read and write than using Promises directly, especially when dealing with multiple asynchronous operations in a row.

To mitigate callback hell, you can:
```javascript
async function fetchUser() {
try {
const response = await fetch('https://api.github.com/users/octocat');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('An error occurred: ' + error.message);
}
}

1. **Modularize**: Break down your code into smaller, reusable functions.
2. **Use Promises or Async/Await**: These features of JavaScript allow you to write asynchronous code that is easier to read and understand.
3. **Use a flow control library**: Libraries like async.js provide functions for managing and organizing asynchronous code.
fetchUser();
```

Remember, the key to avoiding callback hell is to keep your code structured and manageable, regardless of the specific techniques you use.
A try/catch block is used to handle any errors that might occur during the fetch operation or while parsing the JSON. If an error is thrown inside the try block, execution will immediately jump to the catch block, where the error can be handled. This is similar to how error handling works in synchronous code, making it easier to reason about.

## Pros and Cons

Expand Down

0 comments on commit 7a231b1

Please sign in to comment.