Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Ever wondered how JavaScript Promise works internally? Obviously there is some native browser support involved, right? Nope! We can implement the Promise interface using pure JavaScript, examples are libraries like Bluebird or Q. And itâs much simpler than you may think, we can do so in only 70 lines of code! This will help with gaining a deeper insight into Promises by demystifying the underlying formation. Can also serve as a good interview question, if you are an evil employer (donât be!). Letâs dig into it!
First thing that you notice is that a Promise has three states, so should we:
MAKE new Promise() GREATÂ AGAIN!
Using a class sounds reasonable since we should be able to create a new Promise(). Ah, and letâs name our class something else! Itâs an object that can resolve or reject. Hmm, google thinks that Nancy is capable of those! Letâs go with that:
Now errors thrown during Promise execution like new Nancy(resolve => { throw new Error(); }) are captured by reject. We can also do things like new Nancy(resolve => resolve(42)) except⊠it doesnât do what we want! this.state would be changed to states.resolved, but we also need this.value to be 42! Letâs change the resolve and reject definitions:
We used a Higher-Order-Function, getCallback, to avoid repeated code for resolve and reject. Our resolve(42) now works as expected.
Time for the beefier stuff! The infamous âthenâs. The then interface allows a Promise to be chained, which means it should return a Promise. First we create Nancy.resolve and Nancy.reject syntactic sugars:
This allows us to write our new Nancy(resolve => resolve(42)) as Nancy.resolve(42). Now letâs see what we expect from then:
then has different behaviour in rejected and resolved states. That means lots of âifâs, or⊠maybe we can do better?
As you see, no if! Weâve implemented a mechanism for âshifting the gearâ, our state machine behaves differently on each gear. That changeState function in line 18 does what all those condition checks would do for us, voila!
Promise, the âState Machineâ
One caveat: Nancy.resolve(42).then(() => { throw new Error(); }). This should result in a rejected state, but throws the error instead. Not to worry! Our friends at TC39 have a proposal that we are just going to implement. Introducing Nancy.try:
You may think implementing catch is about as much hassle. Think again! Itâs as easy as inverting then.
Now this works:
Two other things that we should fix:
Ignoring subsequent calls to resolve and reject and unpacking a Promise value on resolve (and not reject). We address both these issues in getCallback by moving the previous value assignment and changeState call to a new function, apply:
Well, no escaping the âifâs this time Iâm afraid⊠until the day that match comes around!
Itâs probably time to acknowledge the elephant in the room. Whereâs async in all this? Right, maybe you think itâs going to be a lot of work? Save for a good laugh (spoiler: we are 7 lines away)!
In order to create an async scenario, we first write the Nancy version of the popular delay function:
We should also accommodate for multiple then and catch on a single Promise:
The problem is, our code knows how to handle then and catch on a resolved or rejected state, we just need to hold up until the state arrives there. Our bigger problem is that we need to return a Promise right now! Hmm, well, those are not really problems, they are actually the solution! Letâs do what we just said:
We cashed both the call to then/catch and returned Promiseâs resolve in a laterCall. We call these at the end of apply later. Boom!
We may not be particularly proud of the verbose code of our callLater definition. Not to worry though, one day we will re-write it with the pipe syntax.
Hereâs our code in its final glory:
Hey, we did it! A functional Promise named Nancy in exactly 70 lines of clean code. Hooray!
Another good exercise is to implement Nancy.all and Nancy.race, but I leave that to the beloved reader. You can find the code for this article in this repository. Hope itâs been an interesting read!
Implementing JavaScript Promise in 70 lines of code! was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.