Javascript Promises: part I
Javascript Promises can be really confusing. I had some troubles understanding its details. And the details make a difference in development.
So, I am starting my first series, and, of course, this series will be about Promises.
Fasten your seat belts and let’s start!
What is a Promise?
A Promise is a promise (as the name says) of something. Basically, a Promise is what a function returns when its result is not ready yet, but will be any time in the future.
Javascript has this behavior because it works on browsers, and if something blocks the execution it will freeze the page and the user experience will suffer.
If you need to fetch something from the web, or to make a query on the database it will not return immediately, it will return a Promise of its content.
.then()
and .catch()
methods
Nothing is better than an example. Let’s fetch the informations about my user at GitHub’s API. In order to make this request, I will use the axios library.
const axios = require('axios')const promise = axios.get('https://api.github.com/user/diegohq')promise.then(res => console.log(res))
The axios.get
function returns a Promise, not the API content. In the next line I add the then
method, this is an important method.
The then
method is executed when the Promise finished, or we might say when the Promise is resolved. The then
method receives the resolved value, in our case the API content.
So, it starts executing the then
method. In our case, it simply logs the object on the console.
But, if something went wrong? Well, there are two ways to threat this error. The first one is using the then
method. It can receive a second parameter, with the error:
result.then(
api => console.log(api),
err => console.error(err)
)
So, if something goes wrong, the second parameter will be executed, better than the first one. In our case, it will log the error on the console.
If something goes wrong only the second parameter will be executed. If nothing goes wrong only the first parameter will be executed.
And, as I said, there is a second way of doing so…
The .catch() method
As the name suggest (remembering the try-catch
block), the catch
method receives the error. Let’s rewrite the last code we had:
result.then(api => console.log(api))
.catch(err => console.error(err))
It does the same thing. If something goes wrong, the catch
method will be executed, better then the first parameter of then
method.
But, if we inform both the second parameter of then
and the catch
method?
result.then(
api => console.log(api),
err => console.error('Then second parameter')
)
.catch(err => console.error('Catch'))
In this case, the error will be caught by the then
method and will log Then second parameter
. The catch
method will never be executed.
.then() and .catch() methods are Promises
Yes, I know, it can be confusing. But it’s fundamental to understand it. And it also explains how the catch
method works.
We can chain as many then
and catch
methods as we want. Let’s revisit this code and try to understand what is happening:
result.then(api => console.log(api))
.catch(err => console.error(err))
Let’s assume the Promise is throwing an error, and here we might say the Promise is rejected. So, the then
method will be called, however it can’t receive the error. Then this promise (the then
Promise) is rejected, the chain continues and the catch
method is called and it handle the error.
We can also chain several then
and catch
methods.
result.then(api => console.log(api))
.then(res => console.log(2))
.then(res => console.log(3))
Assuming, there is no error, it will log the API content, the 2
and 3
.
Now, let’s assume the API throwed an error:
result.then(api => console.log(api))
.then(res => console.log(2))
.catch(err => console.error(err))
.then(res => console.log(3))
.then(res => console.log(4))
.catch(err => console.error(err))
What will appear on the console?
The first then
method can’t handle the error, so the execution goes to the next then
method, but the first method rejected the Promise then the second method receives the error. Since the second method can’t handle the error neither, it chains the execution.
Note that neither then
methods logged anything on the console.
Now, the catch
method appears, handles the error and continue the chain. Here, the error already were theated so the next then
method can execute and the next after that.
So, the console will log the error, the 3
and the 4
.
If any error were thrown on the last twothen
methods, the lastcatch
would handle the error. (Note, if the error were thrown on the console.log(3)
then
method, neigher 3
and 4
would be logged; if were thrown on the console.log(4)
only 4
wouldn’t be logged).
Important note
Promises are always executed when they are created. They don’t wait until a then
method to be executed.
You can create a Promise without any then
or catch
and it will be executed! The only difference is that there’s no method to be executed when the Promise resolves or rejects.
So, it’s all for this article. In the next part we will talk how to create our own Promises. See you there!
Cheers!