Promisification in JavaScript: How to and When is It Safe? | by Bartosz Salwiczek | Apr, 2022

The way to flip a operate that takes a callback right into a promise

As JavaScript builders, most of us hate working with callbacks. Lots of you most likely heard in regards to the callback hell and the way it ruins the readability of the applying. If we’re writing our code we have now a selection to make use of Guarantees, however there could also be build-in features or ones from exterior libraries that use callbacks.

Why not flip them into guarantees then?

On this article, I’ll present you how to do this and when it’s secure to do this — because it brings some penalties.

Let’s begin with an instance. Suppose you may have a operate that accepts the callback:

To run the operate we have to present a callback that has two arguments — outcome and potential error.

Now let’s say you need to use it in your stunning async/await code. There are two paths you possibly can take.

One of the best and easiest method is to make use of an already applied methodology for turning a operate that accepts a callback right into a promise. In the event you’re utilizing node.js there may be promisify methodology in utils bundle suited proper for it. On the frontend, you need to use a well-liked es6-promisify bundle.

Instance with promisify from utils:

After utilizing promisify our operate is was a promise. We are able to now use .then / .catch or await / try-catch on it.

When utilizing build-in promisify, operate that you simply need to promisfy should comply with a regular:
1. Have callback because the final argument.
2. Callback must take error and outcome as arguments on this precise order.
You may learn how you can overcome this limitation here.

However… what’s going underneath the hood?

To higher perceive it, let’s promisify the offered operate by ourselves. Let’s begin with defining how we need to name it. It’s gonna be analogous to promisify from utils:

Right here is one attainable implementation of customPromisify:

It’s just a little sophisticated, so let’s break it down.

  1. line #2: customPromisify return a operate that we’ll cross the arguments of the unique operate to. Within the given instance 'a' and 'b' parameters can be current inside args array.
  2. line #3: The returned operate returns a Promise, so we will connect .then and .catch (or use await) to it.
  3. traces #4–7: Inside a promise, we create a customized callback that can resolve or reject a promise accordingly.
  4. line #8: Then we have to add the customized callback to the arguments listing so it’s handed to a operate (fn) and executed when wanted.
  5. line #9: Lastly, we name the offered operate (fn) on the args array containing customCallback.

That’s it! Now we have a solution to promisify a operate.customPromisify may be expanded to just accept extra callbacks or non-standard callbacks.

If you wish to see extra personalized instance of promisification, you possibly can take a look at tenth step in How to Develop React Chrome Extension for Medium in 26 Steps.

Now you already know how. Let’s reply when to do it.

To reply that we have to understand one essential distinction between promise and callback.

Promise can solely have one outcome, whereas callback could also be referred to as a number of instances.

The consequence is that you could watch out whereas altering a operate that accepts a callback right into a promise. There are some features that won’t act the best way it’s possible you’ll assume after promisification.

Unsafe promisification

Are you aware setInterval() operate? It takes a customized operate as a callback and executes it each X milliseconds. Right here is an instance:

It’s going to print "take a look at" each 1000ms till you kill the method or use clearInterval().

Let’s flip it right into a promise:

customPromisify has been modified just a little for this case. Callback solely accepts one argument now. It’s also added as a primary argument to args listing, so it matches the best way setInterval is applied.

That is the execution of the above code:

"take a look at" is printed as soon as, as a result of a promise may be resolved solely as soon as. Furthermore, setInterval isn’t cleared, so this system hangs.

Conclusion

setInterval just isn’t candidate to promisify. Truly, any operate that calls its callback a number of instances shouldn’t be promisified.

I hope that after studying this text you perceive how you can flip a operate that takes a callback right into a promise. Extra importantly, you now know that it’s not at all times secure, so it’s best to fastidiously look into the documentation and examine if the callback will now be executed a number of instances.

More Posts