JavaScript Ninja — Understanding Promise

Welcome to the JavaScript Ninja series. This is my first post on this topic and also on the medium blog. My agenda is to share my learning’s and dispel some myth about how certain things work or how it is kind of coded.

In this story we will try to dissect the concept of Promise and implement a bare-bone version from scratch. If you are a JavaScript developer, at some point you have to deal with some sort of Promise library.

Also, if you are using frameworks like Angular, React, Ember or other, you will or have already encountered some variations of Promise implementation.

Prerequisite:

Basic knowledge of JavaScript, understanding of “this”, context, callback.

If you are still interested, lets begin by understand the concept of Promise and how it can be implemented in JavaScript.

Please note our goal is to understand the concept from “First Principle” and we are not aiming to write production code, but then we will try to follow as much better practices as possible as long as I can keep the explanation simple.

First things first. There are lot of resources on the internet with great write-ups on JavaScript. I am inspired by many, but specifically I like articles/videos by Derick Bailey of watchmecode.net (NOTE: I am in no way affiliated to Derick or his website, but thought of sharing as I learned a lot from his blogs and videos).

Feel free to share your thoughts, suggestions, edits, tips in the comment section, or alternative implementation that will clear up the concepts.

What is a Promise?

Primarily a Promise object represents the eventual completion or failure of an asynchronous operation and kind-of helps avoid the callback hell (though the primary purpose is not to solve the problem of callback hell).

In short a Promise is a guarantee that on execution of some asynchronous task, the completion status or the rejection status or the errors, if any will be communicated to the calling program in a guaranteed way.

Also one side benefit is Promise make asynchronous code look like sequential code.

Without promise our asynchronous code may look like the below figure. The image is adapted from google images (SO).

There are various Promise library and one of the widely used one is rsvp.js available at https://github.com/tildeio/rsvp.js/.

The standard reference for understanding Promise is also found at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise.

In our implementation we will stick to two approaches for designing the API. We will not implement all the features but the most important one, then resolve and reject method, with a bit of error handling.

Let’s take an API first approach to design our library. Also please go through the code comments, as I don’t want to repeat things in the article what can be clearly conveyed in the code.

Approach 1:

Let’s build a simple HTML markup with a button. On click of the button, we need to execute a long running task. In this case we will not make any real AJAX calls, but will use setTimeout for our purpose.

Assume we have a long running task that has to be executed and resolved at two places in this small app. This is just for demo, we can resolve as many times as required.

  1. While Initial Load
  2. On click of the button

Let’s wrap the actual work to be executed in the below method. In the app.js (or any other file) put the below code.

In reality, inside this doLongRunningTask(), we can execute any function, ajax calls etc.

Here’ we are defining our API. We have a MyPromise constructor function (which we haven’t implemented yet, but will shortly).

To simulate long running task we are using setTimeout. In the above case, after 3 seconds the setTimeout will get executed and we will call the resolve() method of our promise object to indicate to the calling function/client that the work is completed.

To execute this function we will invoke it.

At this point our API is slowly evolving. The doLongRunningTask() should return our MyPromise object. We can subscribe to get notified on the task completion by calling the “then” method.

Note here that we can chain the method calls and we can also subscribe multiple times.

Also, if any error happens in the execution, we have the catch method as well.

Additionally, we also want to get notified when the action is completed on button click as well. Note here that the act of clicking the button, the the promise resolution may not happen at the same time.

It may also happen that when the button is clicked the promise is already resolved, as we started the work on page load itself. In that case, the then() method should be immediately executed.

Here’s the code for button click. No fancy jQuery. Just pure JavaScript joy :)

So, far we have developed our API usage pattern, now lets look at the actual implementation of MyPromise, constructor function.

Lets begin with the constructor function. The code is well commented. I am sticking to ES5 (and not using modern ES6 features). The constructor function is invoked by the client by using new MyPromise() as demonstrated earlier.

In case you are creating the promise code in a separate file like “MyPromise.js”, make sure you include it in your HTML file.

Now, to register success callback, let us implement the then() method. As we can chain the then() method, we have to return “this” as part of return value of the function. Here’s the code snippet.

Now, here comes the resolve() method. This is where the callback will be invoked with the returned data.

Let’s now define a simple catch function to handle error. This is the smallest function.

And finally the reject() method, which will use the error callback to raise error to the calling client.

And lo behold, we have completed our first implementation of our own mini Promise library.

Approach 2:

The approach 2 is almost similar to approach one, but the API will be similar to rsvp.js and the native Promise object of JavaScript. I will put the delta code here for your kind perusal. The only thing that changed here is the constructor function.

Just to show you the usage, we can also use the below native like API for our promise library.

You will observe here that the almost all the API is same , except the way the promise is created.

Lets’ look at the constructor function.

Here’ the important thing is in the constructor function the callback is executed with the context set to the correct instance. Rest of the code is exactly same as our earlier Promise implementation.

Hope you enjoyed reading this as much as I have enjoyed writing it.

If you like articles on similar concepts, feel free to share your thoughts in the comments. Please note, I may have omitted some better practices, error handling for brevity sake.

This is a quick write. In case you need more explanation or clarification, drop me a message in the comment. I will update the story.

The full source code can be found here at jsbin.

Thanks for your time. Cheers and “I Promise to post more similar stories in case you like this !!!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.