DEV Community

Cover image for JavaScript-Promises
Kebean
Kebean

Posted on

JavaScript-Promises

A promise is an object that returns a value which you hope to receive in the future but not right away or immediately. It provides a way to handle asynchronous operations such as fetching data from an API.

For example, Imagine you are at your near town restaurant and you order your favourite meal. Once you are done with your payment, most likely you don’t get the meal right away instead, you get a receipt which is a promise by the restaurant that once the meal is ready, you will get it. After 15 minutes or whatever amount of minutes are up and the meal is ready, you show the receipt and you get your meal. In the bizarre world, you also might be rejected maybe because they’ve just realized they have no more of your ordered meal. I know it sounds unrealistic but for the sake of example just go with it. The whole point of this example is that the receipt is a promise that you’ll get the meal eventually or of course if they can not provide it, they have to reject it and in a non-JavaScript world, you will get a refund.

In the JavaScript world, the common example of using promises is going to be “HTTP request” where you set up the request and of course, you don’t get a response right away because it is an asynchronous operation. Only when the server responds, do you either get the data that you’re looking for or you get an error because maybe the URL is wrong..

You can achieve the same using callbacks but the primary purpose of using promises over callback functions is to avoid callback hell. Also, promise allows us to write sync code in a synchronous fashion.

Since we can have async/await in JavaScript, a common practice is to use promises with async/await because async/await provide a cleaner syntax.

          **Setup for creating a promise**
Enter fullscreen mode Exit fullscreen mode

As far as the setup, you need to create a constructor where you pass in the callback function with two arguments. Example:

const promise = new Promise((resolve, reject)=>{
})
Enter fullscreen mode Exit fullscreen mode

The common practice is to use resolve and reject arguments but you can call them anything else and that is going to be okay.
The resolve and reject arguments are functions themselves and when it comes to promises, promises can be in either of 3 states:
pending(initial state where the promise is neither fulfilled nor rejected),
rejected(the operation failed, and the promise knows why it’s failed) or
fulfilled(the operation completed successfully, and the promise has a resulting value).

Once a promise goes from pending to being rejected, you can’t go back which means it is a one-way street. Initially will always be pending waiting for that result and then you have either of these two choices: either it’s going to be fulfilled or it’s going to be rejected. Here is an example to showcase that you will always start with the pending state:

const promise = new Promise((resolve, reject)=>{
})
console.log(promise)
Enter fullscreen mode Exit fullscreen mode

image1

From the above screenshot, the promiseResult is undefined because we haven’t done anything in the promise and as far as the state, it is pending which is always the default setup.

Since resolve and reject are functions themselves, you can invoke them like this:

const promise = new Promise((resolve, reject)=>{
     resolve()
})
console.log(promise)
Enter fullscreen mode Exit fullscreen mode

Image2
As you can see above, the promiseState now is fulfilled. In the resolve() callback function, you can pass in some kind of value like imagine a scenario where you are pinging the server trying to look for data and if you want to pass this data to your application, you will have to pass it through resolve(). Long story short, you can pass data in resolve() but nothing stops you from just invoking resolve() function without any data.
If you want to pass the data in resolve(), you simply pass it in the function as an argument. Example:

const promise = new Promise((resolve, reject)=>{
     resolve("Hello good people")
})
console.log(promise)
Enter fullscreen mode Exit fullscreen mode

Image3
The PromiseStatus is now “Hello good people” because that’s what passed as the data.

The same goes for reject where it can be invoked with or without data. An example where it shows some rejected message:

const promise = new Promise((resolve, reject)=>{
     // resolve("Hello good people");
     reject ("There was an error in your application")
})
console.log(promise);
Enter fullscreen mode Exit fullscreen mode

Image4

How to access values from callback functions(resolve, reject) in promise
You can’t do promise.value because you can’t say to the promise object “Hey, get me the value” This can’t work but to access the value, you’ll need to use other methods and those methods are .then()[this is for resolve()] and .catch()[this is for reject()].
Here is how they work
.then()

const promise = new Promise((resolve, reject)=>{
     resolve("Hello good people");
})
console.log(promise)
promise.then(data=> console.log(data))
Enter fullscreen mode Exit fullscreen mode

Image5
Boom! Now you got the value in the console.
.catch()

const promise = new Promise((resolve, reject)=>{
     // resolve("Hello good people");
     reject("There was an error in your application")
})
console.log(promise)
promise
.then(data=> console.log(data))
.catch((err)=> console.log(err))
Enter fullscreen mode Exit fullscreen mode

Image6
Boom! You got the value in the console as well.

You may be asking yourself well, what will be the usecase for using these arguments?
The idea is that there is going to be some kind of condition and based on that condition you either get the data, meaning you will successful resolve the promise or it’s going to be rejected.It’s as simple as that like a scenario where you’re pinging the server and if you get the data back, you go with resolve() and pass in that data to your application using .then(). Otherwise if there is an error , you reject it ofcourse.

example where we setup a promise based up on a condition

const value = 2;
const promise = new Promise((resolve, reject) => {4
    const random = Math.floor(Math.random() * 3);
    console.log(random)
    if(random == value){
         resolve("You guessed the correct number");
    }else{
         reject("Wrong number ");
    }
});
console.log(promise);
promise.then(data=> console.log(data)
).catch((err)=> console.log(err))

Enter fullscreen mode Exit fullscreen mode

Image7
From the console, since the random number didn’t match the value, the promise was not fulfilled hence throw the error: “Wrong number” else if random number match the value, then the promise will be fulfilled:

Image8
Boom! Now since the value match random number, the promise is fulfilled and the message in resolve() function from the console is displayed.

                   **Conclusion**
Enter fullscreen mode Exit fullscreen mode

By concluding, you can say that promise make it easier to write and manage asynchronous code in JavaScript. They provide a more elegant and structured approach to handling asynchronous operations, making the code more maintainable, readable, and more error-resistant.
Happy coding!! and thanks for reading.

Top comments (2)

Collapse
 
chimamanda16 profile image
Chimamanda16

Been struggling to understand this for a while now and I finally got it. This is a great article. Thank you!

Collapse
 
kebean10 profile image
Kebean

My pleasure!

I'm glad it helped @chimamanda16, Happy Coding