Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

19/04/2020 Building your own `promises` in NodeJs - NM - Medium

Only you can see this message


This story's distribution setting is o . Learn more

Building your own `promises` in NodeJs


NM
Apr 13 · 5 min read

One way to understand the promises functionality of NodeJs is to try and attempt to
build a function which behaves like one. As a programming exercise it is fun and a good
challenge to implement our own promise like functionality.

In this article I will explain the version I came up with up. It makes use of recursion and
also uses some of the concepts of functionals programming.

How will the clients use our promise function?


The first step is determine the interface of our promise function. We want our clients to
be able to perform something like this:

Let us consider a simple example:

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 1/8
19/04/2020 Building your own `promises` in NodeJs - NM - Medium

function promise is our home-grown equivalent of

new Promise((resolve,reject)=>{...})

Our client would want to use the result of our promise and would want to chain a list of
functions and a function to handle error.

Note that the function addX is a higher-order function, its a function that returns another
function.

In order to simplify the implementation let us define the interface in the following
manner:

Functionally it is similar to the then,catch chain of functions. Possibly it is a bit cleaner

because we can now supply an array of functions which are applied serially. We can also
supply the error handler as a seperate function.

Having defined this interface for our clients, let us attempt to implement it.

Version 1 of implementation

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 2/8
19/04/2020 Building your own `promises` in NodeJs - NM - Medium

promise can be defined as a function takes a function fn and returns an object, which has a
function called pipe defined in it.

The pipe function as discussed takes an array of functions to invoke when the result is
resolved and error handler to invoke if there is rejection (in case of an error).

The function fn is passed by the client when it creates a new promise. It is a function
that needs to be passed with two parameters: a resolve function, which the client
invokes it wants to resolve a result and a reject function which it will invoke it wants to
reject the promise invocation.

When the resolve is invoked by the client code, we want to get the result and pass the
result through the pipeline of functions setup earlier by the client:

resolve → result → invoke add1 → result → invoke add2 → result → invoke show

The result of the resolve has to passed to add1, whose result we pass it onto add2 and
its result is passed onto show.

This provides us a clue on how to implement our promise function. For the sake of
simplicity let us ignore promise rejection and focus only on promise resolution.

We want to trigger promise resolve (or reject) by invoking fn function supplied by the
client. But we want to capture result that is resolved and then pass the result to the pipeline
of functions

We could use javascript reduce function on array of functions to process the result:

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 3/8
19/04/2020 Building your own `promises` in NodeJs - NM - Medium

This works and shows the result of 203. GIST:


https://gist.github.com/nmjmdr/a4cc5d5d9cd97c88d7a6fbf71929526f

There is one issue with this implementation. Any promise library worth its salt allows
chaining of promises. What this means it allows the functions in the pipeline to return
promises:

As you can see addX is now higher order function that returns a function which instead
of returning a result directly now returns a promise.

As expected the promise implementation breaks. It is returning the promise directly


instead of waiting to resolve it. The implementation of promise should be evaluating
any intermediate results that turn out to be promises instead of results.

Thus:

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 4/8
19/04/2020 Building your own `promises` in NodeJs - NM - Medium

This hints that we could follow this approach:

We check the result of a function in the pipeline, if it is a promise, we want invoke pipe
function of the returned promise, and passing the remaining functions in the pipeline as
functions parameter.

Importantly we want to break the reduce loop to be able to invoke the pipe function of
promise returned as an intermediate result.

We can no longer use reduce for our implementation as it does not allow breaking the
loop. We could use a for loop, but keeping in line with our functional programming
approach, let us a recursive function to loop.

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 5/8
19/04/2020 Building your own `promises` in NodeJs - NM - Medium

We have redefined the pipe implementation to use recursive function called loop to
loop.

Note the use of ES6 array destructing feature to obtain the the first function in the array
as f and the remaining elements as fs :

Now that we are looping instead of using reduce we should be able to stop the loop and
invoke pipe on the returned promise (if the intermediate result is a promise):

And doing that works!

The result is returned after 3 seconds as expected (compute — resolves after 1 sec, and
both addX functions also resolve after a second each).

Now the only thing that remains to be addressed is the error handling:

We need to re-introduce the errHandler parameter to pipe function. When we invoke


fn function provided by the client, we need pass a reject function as well so that client
can invoke it wants to reject the promise invocation. Addressing these two points give
us the following code:

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 6/8
19/04/2020 Building your own `promises` in NodeJs - NM - Medium

Note that I am setting a default error handler if in case the error handler is not passed
by the client.

We started with an interface of our choice for our promise library and we implemented
it using some of the concepts of functional programming and some recursion.

Two part video about the same topic:

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 7/8
19/04/2020 Building your own `promises` in NodeJs - NM - Medium

JavaScript Promise Asynchronous Design Nodejs

About Help Legal

https://medium.com/@narasimha.gm/building-your-own-promises-in-nodejs-a4fad83e0a08 8/8

You might also like