Promises – Part 2 – Promise definition

Hopefully part 1 made it clear why promises can be useful in an asynchronous language like JavaScript. I think it’d now be best to talk a bit more about what a promise is and how exactly it works.

A promise is an object that defers a future state in the same way a callback can be used and is a cleaner alternative. To clarify what I mean by cleaner, there is a concept in programming known as “Callback Hell” which describes when functions become nested and difficult to read through the use of callbacks, here’s an example:

a(function (resultFromA) {
    b(resultFromA, function (resultFromB) {
        c(resultFromB, function (resultFromC) {
            d(resultFromC, function(resultFromD) {
                console.log(resultFromD);
            })
        })
    ))
});

You probably get the idea that with more complex functions, this can get messy fast! (Check out callbackhell.com for a more thorough explanation)

Returning to what a promise is, a promise is a placeholder object that represents the result of an asynchronous operation. It holds the current status of the operation and can notify us when the operation either succeeds or fails. A promise can exist in three different states:

  • Pending – the promise’s outcome hasn’t yet been determined, because the asynchronous operation that will produce its result hasn’t completed yet.
  • Fulfilled – the asynchronous operation has completed, and the promise has a value.
  • Rejected – the asynchronous operation failed, and the promise will never be fulfilled. In the rejected state, a promise has a reason that indicates why the operation failed.

(These definitions were taken from Spring.IO)

The only state that a promise can change from is pending to either fulfilled or rejected and once it reaches that point, it can not change again.

Promises have a .then() method which can be used to handle the eventual result of the operation and takes one parameter as a function to execute after the promise has resolved.

In the event that a promise is rejected, a .catch() method can be used as an error handling function, like so:

promiseValue.then(function(value) {
    console.log(value);
}).catch(function(error) {
    console.log("There was an error", error);
});

The .then() method returns another promise which means it is possible to chain this method resulting in a chain of promises without having to nest the functions and avoiding the problems we would face with a series of callbacks.

Promises can be created using new Promise which then takes a function. This function takes two parameters: resolve and reject. These are methods that signify the promise is fulfilled. Any errors should be passed to reject(). Data that has been successfully retrieved should be passed to resolve(), if you need to use it. Otherwise, you can call resolve() with nothing passed in if this does not matter. Here is an example using the ES6 version of promises for how this would look:

var promiseValue = new Promise(function(resolve, reject) {
    asyncFunctionWithCallback(function(err, data) {
        if (err) return reject(err);
        return resolve(data);
    });
});

 

Promises are being introduced as first-class language features in ES6 and alternatively there are different JavaScript libraries which can handle promises such as Q, RSVP, when or even jQuery. I’ll begin looking at these libraries in the next post.

Thanks for reading! If you’ve got any comments, I’d love to hear from you.

Promises:

Further reading:

Advertisements

3 thoughts on “Promises – Part 2 – Promise definition

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s