7

Struggling with Promises? You Are Not Alone!

 2 years ago
source link: https://dev.to/polymathsomnath/struggling-with-promises-you-are-not-alone-530g
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Struggling with Promises? You Are Not Alone!

Do you like to cook? I’m not sure about you, but I enjoy cooking. I usually cook by myself, although I’m not opposed to having some help.

Many times you’ll find yourself in a situation where you will need something in the middle of cooking and that damn thing isn’t in your house and you have to ask someone to get it for you while you’re cooking. In the meantime, you keep doing your job!

You may be familiar with this way of doing things — in programming languages — we refer to it as asynchronous.

We often do things asynchronously in programming. That is we initiate something and before even it completes we initiate some other task.

In JavaScript, we rely a lot on asynchronous operations — whose results we don’t have yet but will at some later point.

JavaScript in itself is not asynchronous but it supports asynchronous programming.

ES6 has introduced an idea that makes handling asynchronous tasks easier: Promises.

A promise is an object — a placeholder for the eventual result.

It is not that we could not do the async operation before. We did!

All we had to do is to make use of Callbacks in a certain way! Doing so was a torture when we needed to do a task when our operation failed.

Promises standardized the way to deal with asynchronous events *and *callbacks.

I’ve seen people struggling with promises. This post aims to assist individuals in comprehending this amazing topic. We will endeavour to gain a proper mental model of promises through real-life examples.

The more you struggle to understand, the less you understand any problem. To understand, the mind must be quiet.

— Jiddu Krishnamurti

Since people forget things but remember stories.

Let us understand promises with this little story

1%2AWhZJwK8xvjdDGnsnlAESKg.png

1%2Aco3JdR-Qq5BB1ds7CaQtog.png

I am not yet a master storyteller! However, the preceding scenario contains all of the necessary information to help you comprehend the concepts of Promises.

Let us take the key points from it and apply them to JavaScript World.

We need a standard description of what a Promise is — nothing better than MDN.

1%2AoJVZUT9eDxjcmmxTr7tORg.png

Let us see, how this definition relates to our story.

1%2AFtNMSdpZsKwT1nIDEgSx7Q.png

The definition makes a lot more sense now!

In JavaScript, a Promise is just an object. It is a placeholder for a value we do not have right now but will have later. It ensures that we will eventually know the result of an asynchronous operation.

Circumstances do not matter — only your state of being matters — what state of being are you choosing?

A promise is nothing more than an object, and it is usual for objects to retain a state. By modifying the state, we do many complex tasks in programming.

A promise is always in one of the three states:

  • pending: which is the initial state — that is neither fulfilled nor rejected.
  • fulfilled: meaning that the operation was completed successfully.
  • rejected: meaning that the operation failed.

1%2A7pNnd_1UDwypRvzeYg9LKw.png

Let us establish a strong mental model by tying the underlying principles to our tale before diving into the code.

1%2AJHbrtdV0UnagP1QaV1m36w.png

How to work with promises?

If we want to use promise in our code, then we must first understand these three fundamental concepts.

  • How a to create Promise?
  • How to Fulfil or Reject a Promise?
  • How to Run a Callback Function — Depending on Whether the Promise Is Resolved or Rejected.

“It is not the answer that enlightens, but the question.”

— Eugene Ionesco

If you understand these three things, dealing with promises will be a breeze.

1%2At9HAhA9ehDB7D14dFAuWzg.png

Let’s take a look at each one individually.

How to create a Promise*?*

We create an instance of a promise using the new keyword with the promise constructor function.

1%2AtMeVXaUM_CHpZ3sXGlFzuA.png

How to fulfill or reject the promise?

The promise constructor function accepts one function as its argument — let us pass in an arrow function (but we could just as easily use a function expression).

1%2ACC3LeEpSGKhndrshT50t8w.png

This function is called an executor function, it automatically receives two arguments resolve and reject.

1%2Av4oUtqmnkQltn1XWPe0Atw.png

Keep in mind — resolve and reject both are functions.

  • resolve is a function which when called changes the status of the promise from pending to fulfilled.
  • reject is a function which when called changes the status of the promise from pending to rejected

It is important to keep in mind you cannot directly mutate the status of a promise — you can call the resolve function to fulfill the promise or the reject function to reject the promise.

1%2AAOOd5xCR_LgcMIiuBPgSrw.png

Both these functions are typically called after an async operation.

To keep things simple, let’s use setTimeout() to simulate the time it takes to search for the Tofu. We’ll assume that it takes your pal five minutes to go out and text you back.

1%2Aqf1pLyDTJvlhTqgJqoPx-g.png

1%2AhcCPqO_opLOi3o0dGLJMBA.png

We refactored our code to include the setTimeout function.

If we get the Tofu — we will call resolve after five minutes, if we can not get the Tofu — we call reject after five minutes.

This is pretty much how you fulfill or reject a promise.

How to Run a Callback Function — Depending on Whether the Promise Is Resolved or Rejected.

The final step is to understand how to execute callback functions based on a promise’s state change. Remember that callback functions are functions that are supplied as an argument to another function.

Callback function means that we will use that function as an argument to another function.

Let us define two callback functions — onFulfilled and onFailure

1%2A_sWxMGiP9K-fxqAdKdX4IA.png

onFulfilled() is the function to be called if resolve is called after the async operation

onFailure()is the function to be called if reject is called after the async operation.

Ideally, there would be more code in your callback functions but we simply log into the console and it serves the purpose.

Going back to our analogy, if we found the Tofu then our promise is fulfilled — we want to set up the table to eat. If the couldn’t find the Tofu then our promise is rejected — we have to start cooking the pasta.

1%2AzAiwSKlhwltUZeP5xZvAGA.png

You may be wondering how to make use of these two callback functions?

When we create a new promise using the promise constructor function the promise object gives us access to two methods — then() and catch()

We can call it using promise.then() and promise.catch().

The important bit here is:

  • If the status of the promise changes from pending to fulfilled by calling the resolve function — the function that is passed to then() function will automatically get invoked
  • If the status of the promise changes from pending to rejected by calling the reject function the function that is passed to catch() function will automatically get invoked

1%2A8KP6GnrNBaeq1bZpJLW2jw.png

In our case, we need to pass

  • onFulfilled function to then()
  • onFailure function to catch()

Both functions are callback functions since they are supplied as arguments to other functions. I’m reminding you of this repeatedly since I’ve seen many individuals get afraid of the term “callback” — there is nothing to fear — they are just regular functions.

1%2AwusFSG_8gbm0dxNUYUTy8g.png

1%2AfXY1VLoLsNwaRqfXsIsVpA.png

Our promise code works as expected. But there is room for improvement!

What if we want to send out some data when resolving or rejecting a promise?

That way inside our callback functions we can make use of the value to do something else.

Well, it turns out that we can do that by passing an argument to resolve or reject,

  • for the resolve function, we’ll pass in a string that says Got the Tofu
  • for reject function, we will pass in a string that says Can’t get Tofu

1%2AXYWSjSOSmiy4XuXfkeFHHA.png

1%2A6RorBrRM7TdjsBEcZTP9rw.png

But how do we access these strings in our callback function?

Well, the great thing about a promise is that it will automatically inject the argument passed to resolve as the argument to the onFulfilled callback and the argument passed to reject as the argument to the onFailure callback.

1%2AihtxdnipaHUONsLsjc0gyg.png

1%2A-s9oryvwxOitqLr-pl3lCA.png

You can see that I’ve included parameters to both these callbacks and simply log them to the console.

We would now see the output Got the Tofu Set up the table when the promise is fulfilled or if there is an error and hence a rejection we would see Can't get Tofu Cook pasta.

1%2AhiCMDWkdyM8C12p_YvVJhw.png

One great example of using promises is fetching data from a server; we promise that we’ll eventually get the data, but there’s always a chance that problems will occur.

In a practical scenario, things will be different.

Your result would be:

  • an object(JSON)
  • an array,
  • or any other data type that your async operation returns.

Essentially this is pretty much is the fundamentals of promises in JavaScript. There are a few more details which we will understand in the next article.

“A promise means everything, but once it gets broken, sorry means nothing”

— anonymous

Summary

  • A promise is an object — a placeholder for the eventual result.
  • In past we used Callbacks, to perform the async operation
  • Using callback was a pain especially when you needed to do error handling.
  • Promises standardized the way to deal with asynchronous events and Callbacks.
  • A promise is always in one of three states: pending (the first), fulfilled, or rejected.
  • The operation was completed was marked as fulfilled. The operation was rejected, which means it failed.
  • We create a promise using the new keyword with the promise constructor function.
  • You cannot directly mutate the status of a promise — you can call the resolve function to fulfill the promise or the reject function to reject the promise.
  • We learned How a Promise is created, How to Fulfil or Reject a Promise, How to Run a Callback Function — Depending on Whether the Promise Is Resolved or Rejected.

Note of Gratitude

I wanted to take this last opportunity to say thank you.

Thank you for being here! I would not be able to do what I do withoutpeople like youwho follow along and take that leap of faith to read my post.

I hope you’ll join me in my future blog post and stick around because I think we have something great here. And I hope that I will be able to help you along in your career for many more years to come!

See you next time. Bye!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK