How many articles have you read about the promise in Javascript?
If you are working or learning javascript relevant frameworks, it is natural to encounter a concept called Promise in javascript. What is a promise and why does it occur so often in JS? Before we move on to details of it, I want to briefly discuss background of how we may encounter such concepts.
Let’s assume that we built an e-commerce website. From the initial page after logging in, the user is able to see the current hot deals(recommended) products, my selected products, and other products. So these three categories of the products need to be called from the client to call the apis in the backend server which will then grab the proper sets of data from the database.
Now, there exist various ways of calling the the APIs from the frontend server. Actually from the security perspectives, it is recommended to call an API for each set of the data so that attackers cannot modify the values saved in the client side. However, let’s assume that calling the API takes a lot of cost and time so our strategy here is to call the data once.
So the strategy is that we call two APIs : getUserInformation and getAllProducts. As the names indicate, the first api will fetch user information while the other one fetches all the products. After having the two sets of data, we will filter allProducts with hotDeals flag, and myProducts flag(with my userData) so that, we can come up with three sets of the data: hotDeals products, myProducts, and allProducts.
The problem with what we did just now is that, Javascript does not run synchronously which means, when we filter all the products with the userData that we received from getUserInformation API is not guaranteed to be finished before calling getAllProducts or before filtering the data received from getAllProducts API.
When Javascript runs, it executes each statement(line) accordingly but does not wait for each of the line to be finished. If you have 10 lines of console logs, because each of them will take approximately same time, it seems synchronous, however, if the first console takes a lot more time than the next few, the Javascript will not guarantee the order of the logs.
So now, how do we guarantee the order of asynchronous functions? The answer is of course our beloved promise.
As the name indicates, you can simply understand it as promise promises asynchronous function to be finished. The official definition is a promise is an object that may produce a single value some time in the future. In order to make asynchronous function synchronous, we can return a promise object which we can resolve to run the next function or reject with errors. Here is an example.
It is slightly more complex than what we thought. As you can see the promise1 is a promise object. This promise object has an executor which is a function that is run automatically whenever promise is created. The executor takes resolve and reject which represent the state of the promise.
Because this getUserInfo API function is a function that does not run synchronously since it takes longer than the JS compiler to execute the next line of the code, we have to pass in a callback function that takes in res variable which is the response from getUserAPI. Once we have the response, then it will resolve the promise which changes its state to fulfilled.
What happens when the promise is changed to fulfilled? At line 11, we are calling the promise with then, and we go to inside of this then to do the next executions.
Ok, now we know how to run functions synchronously using the promise and often times, we call it a promisify. However, that is not really everything about the promise since it is pretty deep concept to be honest. Let’s explore some more basics about the promise in details.
Promise has 3 states
- pending : the asynchronous function is not finished
- fulfilled : when asynchronous function is finished and the promise returns the results
- rejected : asynchronous function fails or has errors
With these states in mind, how do we use that resolved state of the promise to run the next sequential function?
The function getData is not a promise object is resolved with data. How do we us that data?
We can use then to receive resolved data from the promise and literally, there is nothing special to it!
Promise Chaining
Another thing to note about promise is that we can connect many promises to each other with then method. When then method gets called, we can return a new promise that is also run by another then when resolved.
When getData is resolved, then gets called with the returned data variable and this also returns a promise that repeats the statement with various chains.
Error catching in Promise
It is also very important to see what kind of error we are getting when there exists an error in promise. There are two ways that we can check the error in the promise.
1. using then() to check the error
2. using catch() to check the error
These two ways both demonstrate the errors. However, it is recommended to use catch when using promise. Let’s take a look at the examples with those two ways of errors.
while getData() function resolves promise properly, if the error occurs in the callback function, it does not properly log the error. However, in this example, it properly catches the error and logs it in console.
As above demonstrates, we can acknowledge more possible exceptions with catch so it is recommended to use catch when using promise.
Wrapping up
As the concept of promise is key in web development in javascript, it is integral to know it in details. I hope the article helped and this is only the beginning of the concept since due to several problems of using promise with then, the javascript has come with another concept, “async/await” that you can explore more. Maybe I should write about one!