In this blog, you will learn the Basic to Pro Level of Promises in Javascript. As we know that javaScript is a single-threaded or synchronous programming language. To achieve the Asynchronous we used the callback functions. For example, suppose we want to fetch some data from Server, we use a callback function to achieve this.
getSomeData((x)=>{ console.log(x); getData(x, (y)=>{ console.log(y); getMoreData(y, (z)=>{ console.log(z); }); }); });
In the above code, I am requesting some data from the server by calling the function, which receives the data inside the callback function. Inside the callback function, I am requesting some more data by calling the getData()
function passing the previously received data as an argument and so on.
This is called callback hell. In callback hell function are nested to another function in the same way which I have shown above . The function is nested inside another, and each inner callback is dependent on its parent.
Now in ES6, Using promises, we can avoid the term ‘callback hell’ and make our code cleaner, easier to read, and easier to understand.
According to MDN, the definition of Promises are,
The Promise the object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
For the above code snippet, we can write using promises
getSomeData() .then((x) => { console.log(x); return getData(x); }) .then((y) => { console.log(y); return getMoreData(y); }) .then((z) => { console.log(z); });
This code is much cleaner and easier to understand than above.
Promises in Javascript
States in Promises
Promises in JavaScript are the same as Promises in real life. Maybe it is unresolved, resolved, or rejected. Suppose you promise someone to meet in next weekend. It may have 3 states
- Pending State: You don’t know, you are available next weekend or not
- Resolved State: You’ve got time, and you’re going to meet your friend.
- Rejected State: You won’t meet. You break your promise.
So every promise starts with a pending state, then fulfilled, and at the end, it may be rejected.
We will understand promises in 2 parts
- Creating promises
- Consuming Promises
Creating Promises
const promise = new Promise((resolve, reject) => {
…
});
we are using Promise Constructor to create a promise, which takes a single argument as a function, also called an executor function which takes two arguments (resolve & reject ). This resolve and reject are also functions and can take one argument, it can be of any data type.
function playCricketPromise() { let userLeft = false let userPlaying = false return new Promise((resolve, reject) => { if (userLeft) { reject({ name: 'User Left', message: 'No one Playing' }) } else if (userPlaying) { reject({ name: 'User playing Cricket', message: 'All Rounder' }) } else { resolve('Join us for Playing Cricket') } }) }
Consuming Promises
playCricketPromise().then(message => { console.log(message) }).catch(error => { console.log(error.name + ' ' + error.message) })
Let’s run the above code in the console.
Look at the above code and try to understand it. I created a function playCricketPromise, with two variables userLeft and userPlaying. If userLeft is true means, no one is playing or if userPlaying is true means the user can play alone. Maybe he is ALLROUNDER (hahaha…)
If both are false, means they are waiting for other players to join the game and play cricket along.
Promise Chaining
The then()
and catch()
methods can also return a new promise which can be handled by chaining another then()
at the end of the previous then()
method.
We use promise chaining when we want to resolve promises in a sequence.
const p1 = new Promise((resolve, reject) => { resolve('I go to market'); }); const p2 = new Promise((resolve, reject) => { resolve('I will buy some foods'); }); const p3 = new Promise((resolve, reject) => { reject('I never came back to my home.'); }); p1 .then((data) => { console.log(data); return p2; }) .then((data) => { console.log(data); return p3; }) .then((data) => { console.log(data); }) .catch((error) => { console.log(error); });
Let’s understand what happened above?
- When
p1
is resolved, thethen()
the method is called which returnsp2
. - The next
then()
is called whenp2
is resolved which returnsp3
. - Since
p3
is rejected, the nextthen()
is not called insteadcatch()
is called which handles thep3
rejection.
Note — Generally only one catch()
is enough for handling rejection of any promise in the promise chain, if it’s at the end of the chain.
Helpers Functions related to promises:
Promise.All
This function accepts an array of promises as input and produces a new promise that either fulfills when all of the promises in the array have been fulfilled or rejects when one of the promises in the array has been rejected.
For Example:
const readBook1 = new Promise((resolve, reject) => { resolve('Reading Book1') }) const readBook2 = new Promise((resolve, reject) => { resolve('Reading Book2') }) const readBook3 = new Promise((resolve, reject) => { resolve('Reading Book3') }) Promise.all([ readBook1, readBook2, readBook3 ]).then(messages => { console.log(messages) })
Output:
Promise.race
The Promise.race(iterable) the method returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.
Summarize:
- Use promises whenever you are using async or blocking code.
- A promise is an object that returns a value in the future.
- A promise starts in the pending state and ends in either a fulfilled state or a rejected state.
resolve
maps tothen
andreject
maps tocatch
- If something needs to be done in both cases use
.finally
If you are interested in learning Destructuring, Spread Operator, Rest Operator then Please Visit Javascript Destructuring Topic.
Reference :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Leave a comment