Use Promises Instead of Callbacks with promisify-node

By  on  

One of the reasons we love promises so much is because they allows us to avoid the infamous callback hell that we've all experienced in these early days of Node.js.  When I see an API that doesn't use the promise pattern, I get annoyed.  Luckily I've found promisify-node, a module that wraps functions or objects in a promise wrapper so you can avoid the callback mess!

There are a few different ways to use promisify-node.  The first is wrapping a single function in the promise:

var promisify = require('promisify-node');

function async(callback) {
  callback(null, true);
}

// Convert the function to return a Promise.
var wrap = promisify(async);

// Invoke the newly wrapped function.
wrap().then(function(value) {
  console.log(value === true);
});

You could even recursively wrap a Node.js module's functions:

var promisify = require('promisify-node');
var fs = promisify('fs');

// This function has been identified as an asynchronous function so it has
// been automatically wrapped.
fs.readFile('/etc/passwd').then(function(contents) {
  console.log(contents);
});

And then you can wrap an object's methods:

var promisify = require('promisify-node');

var myObj = {
  myMethod: function(a, b, cb) {
    cb(a, b);
  }
};

// No need to return anything as the methods will be replaced on the object.
promisify(myObj);

// Intentionally cause a failure by passing an object and inspect the message.
myObj.myMethod({ msg: 'Failure!' }, null).then(null, function(err) {
  console.log(err.msg);
});

Since many front-end APIs are moving to Promise-based APIs, it would be awesome to use something like Promisify to get into the habit of using them on both the server and client sides. Be warned, however, that this module uses a snippet of code to detect function arguments. If you don't use a frequently-used callback argument name, like callback or cb, the promisify-wrapped function may not work correctly.

Recent Features

  • By
    Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event...

  • By
    39 Shirts – Leaving Mozilla

    In 2001 I had just graduated from a small town high school and headed off to a small town college. I found myself in the quaint computer lab where the substandard computers featured two browsers: Internet Explorer and Mozilla. It was this lab where I fell...

Incredible Demos

  • By
    MooTools FontChecker Plugin

    There's a very interesting piece of code on Google Code called FontAvailable which does a jQuery-based JavaScript check on a string to check whether or not your system has a specific font based upon its output width. I've ported this functionality to MooTools. The MooTools...

  • By
    Create a 3D Panorama Image with A-Frame

    In the five years I've been at Mozilla I've seen some awesome projects.  Some of them very popular, some of them very niche, but none of them has inspired me the way the MozVR team's work with WebVR and A-Frame project have. A-Frame is a community project...

Discussion

  1. John Szwaronek

    Since you suggested using this on the front-end, it should be noted that production front-end code is often minified. Minification will change the variable names of the callback params. I’m posting this to prevent someone from doing a bunch of work and then hitting a gotcha going to production.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!