Security News
PyPI’s New Archival Feature Closes a Major Security Gap
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
laissez-faire
Advanced tools
A simple promise class
If your new to the idea of using promises in JS or just this particular implementation of then I recommend you start by downloading this repo and having a quick run through the koans. To do that run.
$ git clone https://github.com/jkroso/Laissez-faire.git && cd Laissez-faire
$ npm install
$ make koans
With component
$ component install jkroso/Laissez-faire
With npm
$ npm install jkroso/Laissez-faire --save
then in your app:
var Promise = require('Laissez-faire')
see the API documentation for usage details
A promise is an Object which boxes a value and provides an interface for accessing it (proxies). They, therefore, are similar in essence to javascript's variables though they don't benefit from any syntactic abstraction. The thing promises have over variables though is that they can provide access to values which don't yet exist in the machines local memory. Accessing a promise's value is always done by sending it a function. This way if the promise doesn't have direct access to its value it can simply store the function and call it when the value arrives. Of course if the promise already has access to its value then there is no need to do anything fancy at all and it can just call the function immediately. The point is the interface is consistent regardless of how long it takes for the value to arrive so we can get on with building abstractions.
If you read the paragraph above you may be left questioning the value of promises since everything I described can be done with simpler methods like continuation passing (CPS). If you implement an API using CPS you are saying I might not be able to deliver my result immediately so pass me a function and I promise to deliver my result to it as soon as I can. The problem with this approach though is that their is nothing left sitting around. The concept of a promise exists but only ephemerally inside the context of the callback. Promise's provide a way of concretising the concept and pulling it out of the hidden context of the callback. By pulling them out its much easier to compose them with other functions. Why hide work from yourself? Lets explore this problem by sequencing two operations which increment a number.
When done with synchronous functions capable of directly returning their result it looks like this:
function inc(a){
return a + 1
}
inc(inc(a))
Now lets pretend a
isn't available right now and try deal with it using CPS.
function getA(cb){
// normally a delay here
cb(1)
}
getA(inc)
Its easy to do the first increment but how do we do the second. To do this we need access to the result of inc
but we can't return
the result from inc
because its called by getA
at some undefined time in the future. I have a few ideas:
inc
take a callbackinc
to call the second. This would rely on getA
forwarding the second callback on to inc
. That gets messy fast and I've never seen a callback taking function implemented to do that.inc
inc
to be.Lets skip the CPS options though and see whats possible when you use promise objects instead of the limited scope promises callbacks provide.
First lets learn the API of promises which is just two methods. read
and write
. read
takes a function which it calls with the promises value as soon as it can. While write
is how you give a promise its value. Thats it. Now lets re-write getA
to return a promise object instead of taking a callback.
function getA(){
var p = new Promise
// normally we aren't able to .write() immediately
p.write(1)
return p
}
getA().read(function(a){
// `a` available here
})
This is all the knowledge of promise objects we need to implement our double inc
program declaratively.
var a = getA()
var b = new Promise
var c = new Promise
a.read(function(a){
b.write(inc(a))
})
b.read(function(b){
c.write(inc(b))
})
Admittedly on the surface this looks like procedural code but thats because its mostly boilerplate which itself is in-fact procedural. What this code says is a
is some value. b
is the inc
of that and c
is the inc
of that. Nothing here manages the ordering and in fact it could be rearranged without affecting the result. Lets see if we can make the code read a bit more like it behaves though. Notice the pattern for creating a promise for the transformed value of another promise is:
We can use a function to abstract away this pattern.
function when(promise, transform){
var p = new Promise
promise.read(function(value){
p.write(transform(value))
})
return p
}
with when
the task of double incrementing a
becomes:
var a = getA()
var b = when(a, inc)
var c = when(c, inc)
This is nice and declarative though in this example we don't really care about storing the intermediate values a
, b
, and c
. I just wrote it that way to keep the flow readable. It could just as readily be written as:
when(when(getA(), inc), inc)
Which highlights a general readability issue when composing functions. Notice how to follow the flow of data in this last example you have to read the code backwards (right to left). Ideally the order our functions appear in our code and the order they execute would be the same. e.g:
getA().then(inc).then(inc)
And in JS that can be achieved by basically just plunking when
on to the promise object as a method. The only change you have to make to when
is to swap the promise
argument for this
. Its a shame really that we have to make such a superficial change in order to convert a function to a method but regardless its nice JS gives us the option to create methods.
So thats it I've introduced you to promises as objects and walked you through a very common abstraction used when working with them. Hopefully, you appreciate that promise objects aren't really abstractions themselves but instead the concretion of the concept of a promise which would otherwise be realised ephemerally and scoped within a single callback (if your were to use CPS). I like to think that by using promise objects in my code I am keeping all my cards on the table face up. With explicit promises adding/removing features from my programs is usually just a matter of adding and removing functions.
There is a lot more to promises but I have chosen to stop here for fear of loosing the forest for the trees. Notably I have not talked about the story promises provide for handling errors.
links:
Just remember that at its heart a promise is just a more robust variable, thats were their value comes from. Its hard to see them for what they are when in JS at least they always come bundled with control flow abstractions.
$ npm install
$ make
Then open your browser to the ./test
directory.
Note: these commands don't work on windows.
FAQs
A promise class
The npm package laissez-faire receives a total of 19 weekly downloads. As such, laissez-faire popularity was classified as not popular.
We found that laissez-faire demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
Research
Security News
Malicious npm package postcss-optimizer delivers BeaverTail malware, targeting developer systems; similarities to past campaigns suggest a North Korean connection.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.