You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A callback is a function passed into another function as an argument and is called after some operation has been completed.
206
206
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
+
207
211
```
208
212
callback(error, values)
209
213
if error, first parameter - error object
210
214
else first parameter - null & rest - return values.
211
215
```
212
216
213
-
callback hell, a situation where callbacks are nested within callbacks, making the code difficult to read and maintain.
214
-
215
217
```
216
218
const userData = { id: 1, name: "John Doe" };
217
219
@@ -225,16 +227,32 @@ function printUserData(data){
225
227
226
228
getUserData(printUserData);
227
229
```
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
+
228
244
## Promises
229
245
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.
231
249
232
250
Promises can be chained and provides easier error handling. So, No Callback Hell.
233
251
234
252
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.
238
256
239
257
Advantages:
240
258
- Chaining: Promises can be chained, improving code readability.
@@ -263,8 +281,11 @@ getUserData()
263
281
```
264
282
265
283
## 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.
268
289
269
290
Advantages:
270
291
- Readability: Makes asynchronous code look like synchronous code, enhancing readability.
@@ -295,148 +316,6 @@ async function processUserData() {
295
316
processUserData();
296
317
```
297
318
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
-
functionfetchData(url, callback) {
309
-
// Simulate an asynchronous operation (like fetching data from an API)
310
-
setTimeout(() => {
311
-
constdata= { 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
-
functionprocessData(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.
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
-
asyncfunctionfetchDataAsync(url) {
410
-
try {
411
-
constdata=awaitfetchDataPromise(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
-
asyncfunctionprocessDataAsync() {
422
-
constdata=awaitfetchDataAsync("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
-
440
319
**Key Differences Summarized:**
441
320
442
321
| Feature | Callbacks | Promises | Async/Await |
@@ -447,10 +326,6 @@ console.log("Fetching data with async/await...");
447
326
| Chaining | Difficult | Easy | Easy |
448
327
| Under the Hood | Basic asynchronous mechanism | Built on callbacks, more structured | Built on Promises, syntactic sugar |
449
328
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
-
454
329
## Closure
455
330
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.
0 commit comments