protips

Logo

This site lists the protips that we shared with eachother in the Slack-channel during the courses.

View the Project on GitHub saltsthlm/protips

This site is deprecated and all the content has moved to AppliedTechnology

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.

Promises Terminology

Before we move on let’s go through some terminology. Oh, I stole this from here. A promise can be:

Terminology for our code

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 and then-ing promises

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))

A more proper example

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);
      });
    });
  });
}
  1. The first line of the function is creating the promise again (new Promise) and setting up the two callback functions (resolve, reject)
  2. On the second line (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
  3. We then initialize a string for the data, on line 3
  4. Line 4 is the way that we receive data using the https-module. We keep appending new chunks of data to the string data.
  5. Line 5 is where we end up when there is no more data to get, (.on('end')). This, in turn, is a callback which will handle the data
  6. Finally, on line 6 we can parse the string data into a JSON object by doing JSON.parse(data)
  7. We are now done and 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) });
  })
}

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.

Summary

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: