Photo by Luis Perdigao on Unsplash
As a developer, I'm constantly looking for ways to write cleaner code.
A year ago I published a library called Premiere, designed to facilitate consuming Restful APIs in the frontend with Javascript. I'm now building a v2 of the library and, in this process, I noticed there was room to make the code cleaner, specifically when it comes to Promises.
In this article I won't explain the basics of Promises, but if you're looking for that, check out Dave Atchley’s article, he does a great job at it.
Disclaimer: Looking for async/await examples? Jump to the end and click on the repository link.
Although Promises are not an exclusivity of HTTP requests, that's what they're usually used for, so this will be the topic of this article's examples.
Let's get started:
This is a straight-forward piece of code and does its job well. However, if we take the same function and add more functionalities, such as caching, it can start getting complex. Here's an example:
As you can see, this example is not as clean as the previous one. fetchAndCacheUser
does way too many things. Sure it's not the end of the world, but ideally each function should do just one thing, so it's easier to test and reuse it.
This problem becomes even more apparent if we add another level of caching. So let's add Promise caching (to prevent two identical requests to be made) and see how it looks:
We're even farther away from "doing just one thing". The more things we add to this code the messier it will get, as well as harder to reuse. If we decide to create a fetchAndCacheItem
for example, it would require us to copy all this code.
The first step for breaking this down is to separate things into more functions, each one taking care of one concern. What we're gonna do is create three functions, each one responsible for doing one of the three things:
The main challenge here this to connect one piece to another, since not all of then need to execute every time (e.g. when cached). To accomplish that we’ll provide callbacks to the cache functions, so they be called when the cache is not present.
Here's the code: (caching methods are hidden for clarity)
Much better huh? We do have more lines of code, but it's a lot easier to read an maintain. Going back to the fetchAndCacheItem
mention, with our concerns separate, we can start to see a path for reusing the same functions.
We've already come to a satisfactory point, but what if I tell you we can do even better?
Taking a look at our last function, fetchAndCacheUser
, we can see that the functions are declared in a reverse order of execution, which can be quite confusing. We also have to declare a new variable and assign it a function for each step, cluttering the code.
To solve these problems, I created the promise-cascade
library. Here's how the fetchAndCacheUser`
function looks like with promise-cascade
:
As you can see, the code is now written in the natural order and doesn't have the const ... = () => ...
clutter.
In some cases that make massive use of these functionalities, it can be helpful to extend PromiseCascade
and create helper methods, so instead of cascade.push(something.bind(this), value1, value2)
, you can call cascade.something(value1, value2)
. You can see examples of this on the GitHub repo.
For more details and examples (including async
), check it out on GitHub. If you like it, I appreciate you giving it a 🌟 star.
pedsmoreira/promise-cascade_promise-cascade - JS Promise cascading made simple_github.com
Don’t forget to spread the love. Throw in your like, share with your friends and colleagues. You're also very welcome to leave your comment below.
You can stay tuned for things I create on twitter.com/pedsmoreira or signing up to my newsletter:
Don't worry, no spam ❤
If you’re into pieces of software crafted with love, I want to invite you to GitShowcase. Come and get your own rockstar portfolio 🤘. cc Victor F. Santos
GitShowcase_Developer, feature your best projects in a plug and play portfolio. The best part, for free._www.gitshowcase.com