Nodejitsu

Save time managing and deploying your node.js app

npmawesome: Easily convert callback functions to promises with Songbird

About the author

Name
Location
Worldwide
nodejitsu nodejitsu

Other popular posts

- Scaling Isomorphic Javascript Code - Keep a node.js server up with Forever - Package.json dependencies done right
- npm cheat sheet - 6 Must Have Node.js Modules
Sign up to our platform for free - get $20 usage

This is a guest post from Alex Gorbatchev and npmawesome.com. Nodejitsu loved what Alex was doing at npmawesome.com and is now supporting the project. Like what you see here? Why don't you contribute on Github?


When working with promises in Node.js, there's a constant friction between callbacks that is Node's defacto interface and your desire to use promises throughout your entire project. Songbird (Github: duereg/songbird, License: MIT) by Matt Blair implements a very clean interface for converting any callback style function to a return a promise instead. It wraps the now famous Bluebird (Github: petkaantonov/bluebird, License: MIT) library. Bluebird has a good collection of helper methods to assist you in going to and from callback world, and Songbird makes it even easier. There's just one caveat.

Songbird does what is generally considered a no-no - it extends Object and Function prototype which gives you a magic promise property on every function. What that means is that you'll want to limit usage to places where you have control over the entire project, and not for generally shared modules. Songbird also wraps the Bluebird library so you don't have to install both. Lets check it out:

npm install songbird  

Usage

var Promise = require('songbird');  
var fs = require('fs');

// callback API
fs.readFile('./package.json', 'utf8', function(err, pkg) {  
  console.log('callbacks', pkg);
});

// songbird API
fs.promise.readFile('./package.json', 'utf8').then(function(pkg) {  
  console.log('promise', pkg);
});

Promise  
  .join(
    fs.promise.readFile('./package.json', 'utf8'),
    fs.promise.readFile('./songbird.js', 'utf8')
  )
  .spread(function(pkg, songbird) {
    console.log('package.json length is', pkg.length);
    console.log('songbird.js length is', songbird.length);
  });

Closing thoughts

While I think it's a great idea to mix in the promise property to Object and Function, however with great power comes great responsibility. I strongly urge against using Songbird in modules that you would distribute on npm because it would have a very big side effect on anyone who dares to install your code. However, when used on a project that isn't made available publicly, Songbird would be a great asset.

Check out source code for this article on GitHub and an interactive example on Runnable. Let us know what you think! It's not every day you encounter a module that boldly extends Object and Function.