Skip to content

Commit b2d6982

Browse files
authored
async await
1 parent c456f08 commit b2d6982

1 file changed

Lines changed: 29 additions & 154 deletions

File tree

JavaScript/functions.md

Lines changed: 29 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,16 @@ Links:
204204
## Callback
205205
A callback is a function passed into another function as an argument and is called after some operation has been completed.
206206

207+
* **What they are:** A callback is a function that is passed as an argument to another function and is executed *after* the first function completes its task. They are the traditional way to handle asynchronous operations in JavaScript.
208+
209+
* **Why they're used:** JavaScript is single-threaded and non-blocking. This means that long-running operations (like network requests or file I/O) shouldn't halt the execution of the rest of your code. Callbacks allow you to start an operation and then specify what should happen once it's finished, without blocking the main thread.
210+
207211
```
208212
callback(error, values)
209213
if error, first parameter - error object
210214
else first parameter - null & rest - return values.
211215
```
212216

213-
callback hell, a situation where callbacks are nested within callbacks, making the code difficult to read and maintain.
214-
215217
```
216218
const userData = { id: 1, name: "John Doe" };
217219
@@ -225,16 +227,32 @@ function printUserData(data){
225227
226228
getUserData(printUserData);
227229
```
230+
231+
* **Callback Hell (Pyramid of Doom):** A major drawback of callbacks is that nested asynchronous operations can lead to complex and hard-to-read code, often called "callback hell" or the "pyramid of doom."
232+
233+
```javascript
234+
// Example of nested callbacks (callback hell)
235+
getData1((data1) => {
236+
getData2(data1, (data2) => {
237+
getData3(data2, (data3) => {
238+
// ... more nested callbacks ...
239+
});
240+
});
241+
});
242+
```
243+
228244
## Promises
229245

230-
A promise is basically an advancement of callbacks in Node. A Promise means an action will either be completed or rejected.
246+
* **What they are:** A promise is basically an advancement of callbacks in Node.Promises are a cleaner way to handle asynchronous operations. **A Promise represents the eventual result of an asynchronous operation.** It can be in one of three states:
247+
248+
* **Why they're used:** Promises make asynchronous code more readable and manageable, avoiding the problems of callback hell. They provide a more structured way to handle asynchronous results and errors.
231249

232250
Promises can be chained and provides easier error handling. So, No Callback Hell.
233251

234252
Promise States:
235-
- pending: initial state, neither fulfilled nor rejected.
236-
- fulfilled: operation completed successfully.
237-
- rejected: operation failed.
253+
* *Pending:* The initial state, before the operation completes.
254+
* *Fulfilled (Resolved):* The operation completed successfully.
255+
* *Rejected:* The operation failed.
238256

239257
Advantages:
240258
- Chaining: Promises can be chained, improving code readability.
@@ -263,8 +281,11 @@ getUserData()
263281
```
264282

265283
## Async-Await
266-
- Async functions helps in writing promises looks like synchronous. It operates asynchronously via the event-loop. It automatically wraps it in a promise which is resolved with its value.
267-
- Await: Await function makes the code wait until the promise returns a result. It only makes the async block wait.
284+
* `async` and `await` make asynchronous code look and behave a bit more like synchronous code, making it even easier to read and understand.
285+
* `async` is used to declare a function as asynchronous.
286+
* `await` is used inside an `async` function to pause execution until a Promise resolves (or rejects).
287+
* Async/await simplifies asynchronous code even further than Promises, making it more concise and easier to follow the control flow.
288+
* It's built on top of Promises.
268289

269290
Advantages:
270291
- Readability: Makes asynchronous code look like synchronous code, enhancing readability.
@@ -295,148 +316,6 @@ async function processUserData() {
295316
processUserData();
296317
```
297318

298-
299-
**1. Callbacks**
300-
301-
* **What they are:** A callback is a function that is passed as an argument to another function and is executed *after* the first function completes its task. They are the traditional way to handle asynchronous operations in JavaScript.
302-
303-
* **Why they're used:** JavaScript is single-threaded and non-blocking. This means that long-running operations (like network requests or file I/O) shouldn't halt the execution of the rest of your code. Callbacks allow you to start an operation and then specify what should happen once it's finished, without blocking the main thread.
304-
305-
* **Example:**
306-
307-
```javascript
308-
function fetchData(url, callback) {
309-
// Simulate an asynchronous operation (like fetching data from an API)
310-
setTimeout(() => {
311-
const data = { name: "John Doe", age: 30 }; // Sample data
312-
callback(data); // Call the callback function with the data
313-
}, 1000); // Simulate a 1-second delay
314-
}
315-
316-
function processData(data) {
317-
console.log("Data received:", data);
318-
// Perform some operations on the received data
319-
console.log("Name:", data.name);
320-
console.log("Age:", data.age);
321-
}
322-
323-
fetchData("some_url", processData); // Pass processData as the callback
324-
325-
console.log("Fetching data..."); // This will execute *before* the data is fetched
326-
327-
// Output:
328-
// Fetching data...
329-
// Data received: { name: 'John Doe', age: 30 }
330-
// Name: John Doe
331-
// Age: 30
332-
```
333-
334-
* **Explanation:** `fetchData` simulates an asynchronous operation. `processData` is the callback. Notice how "Fetching data..." logs *before* the data is actually received. This demonstrates the non-blocking nature of asynchronous JavaScript. Once the `setTimeout` finishes (after 1 second), it calls the `processData` function, passing the retrieved data.
335-
336-
* **Callback Hell (Pyramid of Doom):** A major drawback of callbacks is that nested asynchronous operations can lead to complex and hard-to-read code, often called "callback hell" or the "pyramid of doom."
337-
338-
```javascript
339-
// Example of nested callbacks (callback hell)
340-
getData1((data1) => {
341-
getData2(data1, (data2) => {
342-
getData3(data2, (data3) => {
343-
// ... more nested callbacks ...
344-
});
345-
});
346-
});
347-
```
348-
349-
**2. Promises**
350-
351-
* **What they are:** Promises are a cleaner way to handle asynchronous operations. A Promise represents the eventual result of an asynchronous operation. It can be in one of three states:
352-
* *Pending:* The initial state, before the operation completes.
353-
* *Fulfilled (Resolved):* The operation completed successfully.
354-
* *Rejected:* The operation failed.
355-
356-
* **Why they're used:** Promises make asynchronous code more readable and manageable, avoiding the problems of callback hell. They provide a more structured way to handle asynchronous results and errors.
357-
358-
* **Example:**
359-
360-
```javascript
361-
function fetchDataPromise(url) {
362-
return new Promise((resolve, reject) => {
363-
setTimeout(() => {
364-
const data = { name: "Jane Doe", age: 25 };
365-
// Simulate success:
366-
resolve(data);
367-
368-
// Simulate an error:
369-
// reject("Error fetching data");
370-
}, 1000);
371-
});
372-
}
373-
374-
fetchDataPromise("some_url")
375-
.then((data) => {
376-
console.log("Data received:", data);
377-
console.log("Name:", data.name);
378-
console.log("Age:", data.age);
379-
return data; // You can chain promises
380-
})
381-
.then((data) => { // Example of chaining
382-
console.log("Data processed further:", data.age * 2);
383-
})
384-
.catch((error) => {
385-
console.error("Error:", error);
386-
});
387-
388-
console.log("Fetching data with Promise..."); // This executes first
389-
390-
// Output:
391-
// Fetching data with Promise...
392-
// Data received: { name: 'Jane Doe', age: 25 }
393-
// Name: Jane Doe
394-
// Age: 25
395-
// Data processed further: 50
396-
```
397-
398-
* **Explanation:** `fetchDataPromise` returns a Promise. The `.then()` method is used to handle the fulfilled state (when the data is successfully retrieved). The `.catch()` method handles the rejected state (if there's an error). Promise chaining allows you to perform a sequence of asynchronous operations in a more organized way.
399-
400-
**3. Async/Await**
401-
402-
* **What they are:** `async` and `await` make asynchronous code look and behave a bit more like synchronous code, making it even easier to read and understand. `async` is used to declare a function as asynchronous, and `await` is used inside an `async` function to pause execution until a Promise resolves (or rejects).
403-
404-
* **Why they're used:** Async/await simplifies asynchronous code even further than Promises, making it more concise and easier to follow the control flow. It's built on top of Promises.
405-
406-
* **Example:**
407-
408-
```javascript
409-
async function fetchDataAsync(url) {
410-
try {
411-
const data = await fetchDataPromise(url); // Wait for the Promise to resolve
412-
console.log("Data received (async/await):", data);
413-
console.log("Name:", data.name);
414-
console.log("Age:", data.age);
415-
return data;
416-
} catch (error) {
417-
console.error("Error (async/await):", error);
418-
}
419-
}
420-
421-
async function processDataAsync() {
422-
const data = await fetchDataAsync("some_url");
423-
console.log("Data processed further (async/await):", data.age * 2);
424-
}
425-
426-
427-
processDataAsync();
428-
console.log("Fetching data with async/await...");
429-
430-
// Output:
431-
// Fetching data with async/await...
432-
// Data received (async/await): { name: 'Jane Doe', age: 25 }
433-
// Name: Jane Doe
434-
// Age: 25
435-
// Data processed further (async/await): 50
436-
```
437-
438-
* **Explanation:** The `async` keyword makes `fetchDataAsync` and `processDataAsync` asynchronous functions. Inside `fetchDataAsync`, `await fetchDataPromise(url)` pauses execution until the Promise returned by `fetchDataPromise` resolves. The `try...catch` block handles any potential errors. `async/await` makes the code look much more like synchronous code, even though it's asynchronous under the hood.
439-
440319
**Key Differences Summarized:**
441320

442321
| Feature | Callbacks | Promises | Async/Await |
@@ -447,10 +326,6 @@ console.log("Fetching data with async/await...");
447326
| Chaining | Difficult | Easy | Easy |
448327
| Under the Hood | Basic asynchronous mechanism | Built on callbacks, more structured | Built on Promises, syntactic sugar |
449328

450-
451-
In modern JavaScript development, Promises and especially async/await are the preferred way to handle asynchronous operations. They lead to cleaner, more maintainable, and easier-to-understand code. While callbacks are still used in some situations (especially in older code or with certain APIs), Promises and async/await are the recommended approach for most asynchronous tasks.
452-
453-
454329
## Closure
455330
A closure is a feature in JavaScript where an inner function has access to the outer (enclosing) function’s variables. In JavaScript, closures are created every time a function is created, at function creation time.
456331

0 commit comments

Comments
 (0)