Asynchronous Javascript - Callbacks, Promises, Async-Await | (Clarified everything) |
Credit: Mohtasim Ahmed

Asynchronous Javascript - Callbacks, Promises, Async-Await | (Clarified everything) |


Before going through this article, Read it: Synchronous Javascript and Asynchronous Javascript | How javascript is run |

In that article, we used a function called "setTimeOut" which is an "asynchronous function". Everything was good there. But a problem happened there. That is we can't control the flow of the program as we want. like- " 'cooking completed' was being executed in the end". That's a big problem that we need to deal with.

So, to deal with that, a feature called "callback function" was introduced in JavaScript. Using "callbacks", we can control the flow of a program and a programmer gets more flexibility.

Callbacks:


Output here:

> Taking Order from customer1

> Processing order for customer1

> Order processed for customer1

> Order served

> Cooking completed


But here, we don't want an Output like this. Here, the flow isn't controlled. We want an output like this:

> Taking Order from customer1

> Processing order for customer1

> Cooking completed

> Order processed for customer1

> Order served


Let's fix this step by step. Let's fix the flow and make the code more flexible.

Write down this code:


Here I have converted the codes into little pieces and blocked them into functions. And have taken "Order processed for customer1" into the "setTimeOut" function so that the statements inside the "setTimeOut" are executed at the same time.

Now add these extras to your code:


Here, in each function, I have called the following function that I want to execute after the function. like- I want the "processOrder()" to execute after "takeOrder()" and I want the "orderServe()" to execute after "processOrder()". Also, I want to execute "orderServe()" when "setTimeOut()" is executed.

Now, what if we wanted to control the flow from outside of the functions?


If you run the code, you will see our expected outputs.

A JavaScript callback is a function that is to be executed after another function has finished execution. Any function that is passed as an argument to another function so that it can be executed in that other function is called a callback function.

In the last portion of the code (marked red), functions that are passed, are callback functions.

Now, there is a little problem using callback functions when there are too many functions. like-


Imagine, you have a few more functions. Then you have to add more callbacks here. Then, it will be unreadable for a programmer and hard to debug. And, this problem is called "Callback Hell".

So, to solve this problem, a feature/mechanism named "promise" was introduced in Javascript.


Promise:

The promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It is an asynchronous feature of JavaScript.

A Promise is in one of these states:

  • pending: initial state, neither fulfilled nor rejected.
  • fulfilled/resolved: meaning that the operation was completed successfully.
  • rejected: meaning that the operation failed.

const meeting = new Promise((resolve, reject) => {
  //========== A promise is made ===============

    resolve(something)  //==== To resolve the promise ====

   reject(somthing)       //==== To reject the promise =====
})

meeting
    .then((res) => {
    //========= If the promise is resolved ===============
})
     .catch((err) => {
   //========= If the promise is rejected ===============
})        

Here,

  • A new Promise object (by using "new Promise") is created. The Promise constructor takes a function (executor) that has two parameters: resolve and reject.
  • If hasMeeting is false: The executor creates a meetingDetail object containing details about the meeting. The promise is resolved with the meetingDetail object using resolve(meetingDetail), indicating that the promise has been fulfilled successfully.
  • If hasMeeting is true: The promise is rejected using reject(new Error('Meeting already scheduled')), which indicates that the promise has failed with an error.
  • The 'then' method is called when the promise is successfully resolved. The resolved value (in this case, meetingDetail) is passed to the callback function inside 'then'. This callback logs the meeting details to the console.
  • The 'catch' method is used to handle any errors if the promise is rejected. If the promise is rejected, the error object is passed to the callback inside 'catch'. This callback logs the error message to the console.


What if "hasMeeting = true"?

Promise Chaining:

The code handles the scheduling of a meeting and then adds that meeting to a calendar, using a series of promises to manage the asynchronous operations. Promise chaining occurs when the then method of a promise returns another promise, allowing multiple asynchronous operations to be performed in sequence. Each then in the chain waits for the previous one to be resolved before executing. This approach is useful for managing a sequence of dependent asynchronous tasks.


Explanation:

The 'addToCalender' Function:

  • This function takes meetingDetail as an argument and returns a new promise.
  • Inside the promise, it creates a string calendar.
  • The promise is resolved with this string.

Promise Chaining:

  • First 'then': When the 'meeting promise' is resolved, the result (meetingDetail) is passed to the addToCalender function. addToCalender returns a new promise, which is resolved with the string 'calender'.
  • Second 'then': The resolved value from addToCalender (the calendar string) is passed to the next 'then' method, which logs the message to the console.
  • Catch Block: If any of the promises are rejected, the catch method handles the error and logs the error message to the console.


Promise.resolve() :

If you don't want to 'reject' anything into a "Promise", then you can use "Promise.resolve()" to resolve instead of creating a full "Promise".


Promise.all() :

We have two promises. And to see the resolves from 2 promises, this is how we need to write the code. But there is a better way:


By using "Promise.all([...])", you can resolve all the promises simultaneously.

Promise.race() :

It shows the 'resolve' of the promise that is resolved first. Here because of 'setTimeOut()', promise2 takes time to be executed and is executed after promise1.


Async-Await:

(Turns any function into an Asynchronous Function) | Async function basically returns Promise. And Await works as "then". | 'Async' and 'Await' are used simultaneously.

Asyn => Promise | Await => .then |



Output: Meeting added to calender: Engineering at Zoom at 10:00 AM |

Here, we have just written the previous "Promise Chain" code using async-await. We've declared an async function called "myMeeting" and inside of it, we controlled the flow of the program. First, we executed the meeting function and then we executed the "addToCalender" function.

Now, in this case, How do we catch errors?

This is how we do it:

So, that's all!


Keep in mind: Try to code in an "Asynchronous" way to make the code more efficient and flexible. Try using "Async-Await" instead of callbacks and promises.

Thank You

要查看或添加评论,请登录

社区洞察

其他会员也浏览了