This site lists the protips that we shared with students during our courses
When I first heard about promises I got pretty confused and actually had a period where I rather did callbacks than Promises.
But then I got to know how to make my own promise and it all made a whole lot of sense.
Let’s make a dead simple little function that checks if a number is negative or not. But, let’s make it into a promise.
(You should understand something about passing functions as parameters and what callbacks are before reading this post)
const isNegative = number => {
return new Promise((resolve, reject) => {
if (number < 0) {
reject(Error(`${number} is negative`));
}
resolve(`${number} is positive`);
});
}
This looks a bit convoluted so let’s got through it slowly.
new Promise()
.resolve
- a callback function that we will call when the work is completed without errorsreject
- a callback function that we will call when the work fails for some reasonif (number < 0)
) and reject
or resolve
the promise.Before we move on let’s go through some terminology. Oh, I stole this from here. A promise can be:
As we enter the function isNegative
the promise is pending, as in we are waiting for a result from it.
When we call reject
on line 3 of the function the promise gets rejected.
If the number is not negative we end up on line 5 and the promise is fulfilled
Once the function has executed and we have done either reject
or resolve
then the promise is settled
Speaking of - let’s call our promise.
Calling to our new promise function is very simple:
isNegative(4)
And if you do that … nothing happens. But if you were to console.log it
console.log(isNegative(4))
you would see something like Promise { '4 is positive' }
. The promise is not yet fulfilled. If our function were to take time this would say Promise <Pending>
(we’ll see this later)
In order to make use of our promisfied function, we need to receive the call to the reject
or resolve
somewhere. This place is .then()
.
isNegative(4)
.then(res => console.log(res))
.catch(err => console.log(err.message))
.then
- is what will be called when we invoke resolve
in the isNegative
function. We will receive the result in a callback function parameter called res
. In this case, we just print it to the console res => console.log(res)
.catch()
- is what will be called when we invoke reject
.We have created an Error
object when we called reject
(reject(Error(
${number} is negative))
). Hence our callback function now takes an error object with an error message that we log to the console err => console.log(err.message)
As you can see, writing our own promisified function is not that complicated. And I now hope that you, by understanding the inner workings of promises, understand more about how they work.
Let’s do it again, with a more complicated example. Let’s fetch some data over http(s), and let’s do it by turning it into promises.
Here’s the code, let’s go through it below.
const https = require('https');
function get(url) {
return new Promise(function (resolve, reject) {
https.get(url, res => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
const parsedData = JSON.parse(data);
resolve(parsedData);
});
});
});
}
new Promise
) and setting up the two callback functions (resolve, reject
)https.get(url, res => {
) we do the GET
and pass the url
to get data from, as well as the callback function that will receive the result res
https
-module. We keep appending new chunks
of data to the string data
..on('end')
). This, in turn, is a callback which will handle the datadata
into a JSON object by doing JSON.parse(data)
resolve
the promise by passing the parse data as data to the resolve function resolve(parsedData)
Ok - that was a bit long. Let’s do it again, faster. Here’s a function that wraps the get
we just wrote.
function getPlayer(id) {
return new Promise(function (resolve, reject) {
const url = 'https://swapi.co/api/people/' + id + '/';
get(url)
.then(data => { resolve(data) });
})
}
new Promise
.get
function.then(data)
callback.getPlayer
function on line 4, passing the data resolve(data)
We can now call the getPlayer
promise and receive the result in a .then
callback:
getPlayer(13)
.then(player => { console.log(`We got ${player.name}`) })
We print to the console and see We got Chewbacca
printed in the console.
Promises is a way for us to handle asynchronous execution in JavaScript. It’s easier to read than nested callbacks that often ends up becoming a mess of curly braces.
Writing your own promisfied function is not very complicated and it teaches you a lot about how promises work internally. And that’s not that complicated either - once you understand what it is all about.
More resources: