The JS Bifrost — All that we need to know about Promises
Understanding promises and its methods to solve real-world application problem statements
Welcome back to “The JS Bifrost”, your pathway to the rock-solid foundation for a God-level JavaScript. This is the next article in the series. Our focal point for this one is — Promises in javascript and its methods
A Promise is an object which is used to represent the eventual fulfilment or failure of an asynchronous task. It will produce a value as the result.
Little confusing isn’t it ??? Let’s understand in layman’s language.
We can say, a promise is some kind of agreement that will be fulfilled or denied if a certain condition is met. Also, instead of doing it right away, it will rather give value in near future.
Note: The IPL (Indian Premier League) is a professional Twenty20 cricket league in India.
Let’s understand promises with an IPL(I Promise ‘ll) Auction example
When a Franchise buys some player in an IPL auction let’s say Virat Kohli with the hope, that player will perform for them and win matches. We can say the player promises to a certain franchise he will score runs. After the tournament, if that player scores run in winning cause we can say that promise is fulfilled or resolved contrarily if he unable to score runs as expected we can say that promise is rejected or not fulfilled.
How does Promise Work?
When players came in IPL auction let’s say Pat Cummins with some start base price say 2 crores. Multiple franchises (KKR, CSK, MI, etc.) can place their bids for that player at the same time which should be higher than the base price let’s say 2.5 cr, 4.5 cr, 13cr, etc. This process of biding we can say it is the asynchronous task and multiple biding at the same time we can say multiple tasks are running in parallel which included KKR( promise), MI(callbacks), etc., After multiple bids, one franchise say KKR placed the highest bid say 13cr we can say KKR will get the player and Promise got resolved successfully.
How to create a Promise?
Now that we understand the concept of promise, let's deep dive and see how to implement it in JS.
A Promise can one have of the following states
- Pending
- Fulfilled
- Rejected
Let’s understand these states with a cricketing example as IPL fever is at its peak.
When any team takes review in cricket, it will be in the pending state till the time umpire is checking the necessary things(bats edge, etc.), After sometime when the umpire is fully sure about the decision, then he will decide and give it as out/not-out. The team who got the decision in their favor as out / not-out we can say that the reviewed decision as fulfilled if not as rejected or loss of review for the respective team.
There are methods provided by a promise to handle resolved/ rejected state.
- Then
- Catch
When a promise gets resolved successfully it will call the .then() method where we can perform some operation like returning the resolve. On the other, if we get an error as a response then the .catch() method will get invoked.
In the above example, we are returning a promise object from fetchData method which is having the resolve and reject as callbacks. If the promise gets resolved successfully .then() method will be invoked or if it gets rejected or some error occurred then the .catch() method will be invoked.
Promise.all
It takes an array of promise or iterable as input and will return the result as a single promise. This promise which we got as a result will only get resolved when all the promises which we passed will get successfully resolved. On the other hand, if any promise that we passed as the input to Promise.all method gets rejected or errored out, the result we will get as the promise is as rejected as well.
In the above example, we are declaring three promise p1, p2, p3, and passing them as an array to the Promise.all method, the result which we get when all promises get resolved successfully will be an array of values. On the other hand, if any promise passed as an input to Promise.all method, gets rejected or errors out, the result is a rejected promise.
Promise.allSettled
It takes an array of promise or iterable as input and will return output as an object of promise for each promise whether it is resolved or rejected. This method is useful when we want all promises which we passed as an input to be independent of each other.
In the above example, we are declaring three promise p1,p2,p3, and passing them as an array to Promise.allSettled method the result which we got when all promises get resolved successfully we will get an array or an object containing status and values for each promise as a result. On the other hand, if any promise gets errored out or rejected then we will get that, as a result, like on the right side of example status we got as rejected and reason as value 31.
Promise.race
It takes an array of promise or iterable as input and will return the result as a single promise whether that promise is fulfilled/resolved or rejected whatever is available first we will get that promise as a result.
In the above example, we are declaring three promise p1,p2,p3, and passing them as an array to Promise.race method the result which we got when any promises get resolved successfully we will get that as a response like in left side example we are getting 10 as resolved value. On the other hand, if any promise gets errored out or rejected then we will get that as a result like on the right side of the example we got rejected promise as value 31.
Promise.any
It takes an array of promise or iterable as input and will return the result as a single promise that resolves with the value from the promise. If all promise which is passed as an input is rejected then we will get AggregateError(It is a collection of multiple errors wrapped in single error) as output.
In the above example, we are declaring three promise p1,p2,p3, and passing them as an array to Promise.any method the result which we got when any promises get resolved successfully we will get that as a response like in the left side example we are getting 31 as resolved value. On the other hand, if all promise gets errored out or rejected then we will get AggregateError, as a result, like on the right side of example all promises are rejected.
Promise Chaining
When we need to call multiple dependent asynchronous calls where the result from one is the input for another and so on. This process of invoking one promise from another is called Promise chaining.
In the above example, we are using the multiple .then() method to get the response of multiple resolved method and then at last final response as a result. In case we got some error or any promise gets rejected we can handle it via the .catch() method.
Promise vs Async/await
There is a common misapprehension among the developer that async/await is different from the promise.
Alert! But they are not under the hood async/await uses the promises to function. Below is an example of how async-await looks under the hood.
But async/await indeed makes the developer's life easier when it comes to writing a complex logic or handling multiple asynchronous calls at the same time. It is always tiresome to manage multiple promises or promises chaining calls at the same time, here comes the main advantage which we can get via the use of async/await. let’s understand this via example.
Browser compatibility for Promises and its different methods
all(iterable), allSettled(iterable), any(iterable), race(iterable)
Epilogue
Synchronous Programming model
When you call a function that performs a long-running action, it returns only when the action has finished and it can return the result. This stops your program for the time the action takes.
Asynchronous Programming model
This model allows multiple things to happen at the same time. When you start an action, your program continues to run. When the action finishes, the program is informed and gets access to the result (for example, copying data from disk).
“Who can wait quietly while the mud settles?
Who can remain still until the moment of action?”— Laozi, Tao Te Ching
Programming asynchronously is made easier by promises, objects that represent actions that might complete in the future, and async
functions, which allow you to write an asynchronous program as if it were synchronous.
I hope this article is useful and helps you to understand Promises and its methods usefulness to write you bugless code. Thanks for reading!
Stay tuned for more under our ‘The JS Bifrost’ !!