A really simple promises library
CoffeeScript
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
test
.gitignore
.npmignore
.travis.yml
Cakefile
README.md
bench.coffee
package.json

README.md

Build Status

promqueen

This is a very simple promises library I wrote after reading https://gist.github.com/3889970. I wanted to implement them out of curiosity, but it turned out to be a little harder than I thought.

Promises are a beautiful solution to nested callbacks & error handling, and unless you're writing high performance code (in which case I would ask why you're using Javascript), I believe the payoff in developer productivity is much greater than the performance overhead imposed by the library. See below for benchmarks.

I haven't set out to replicate CommonJS promises (Promises/A, B, etc.), but IMHO, this library has got the gist of it (i.e. chaining promises & capturing downstream error handlers).

Enjoy!

Benchmarks

On my PC, I read a file into memory & wrote it to another file 200,000 times using both callbacks & promises, and the difference in performance is negligible.

  • callback elapsed: 9,543ms
  • promqueen elapsed: 10,190ms

I think ~500ms for 200,000 promises is a fair tradeoff.

To run the benchmark: coffee bench.coffee

Example

A naive file copy example:

fs = require 'fs'
promqueen = require 'promqueen'

promoteErrCallback = promqueen.promoteErrCallback

readFile = promoteErrCallback(fs.readFile)
writeFile = promoteErrCallback(fs.writeFile)
# Note: promoteErrCallback is used for callbacks with err as the 1st parameter.  Otherwise, you can use promoteCallback if err isn't used (e.g. fs.exists)

readFile(__filename).then (err, data) ->
	data.toString()
.then (result) ->
	writeFile 'temp.txt', result
.fail (err) ->
	throw err

Things I still need to think about

Once a promise fails, it propagates that failure (and its arguments) to all downstream handlers (with fail handlers being executed). Any value returned by a downstream fail handler is ignored.

Should downstream fail handlers be permitted to bring a failed state back to a resolved state, pass different arguments or halt the propogation? I'm not sure what the behaviour should be yet.

And also, should a "finally" type clause be implemented?

Interesting reads