Promises <3 Callbacks

My new found love for promises is well documented on this very blog. Once you start using promises, it’s hard to go back. It is also very easy to forget the challenges in understanding promises in the first place.

I recently came across this article that talked about how node should have been built on top of promises to begin with, and how they missed a huge opportunity by going with callbacks.

Now, while I love the promises, considering the sort of steep learning curve, I still see value in callbacks and libraries like Async.

One of the places where I find Promises to be extremely limiting is when dealing with events. Promises can only be resolved once. They become useless for dealing with streams and events. (The progress event can be used here, but it’s an optional part of the Promises/A+ spec, and many libraries don’t even implement it)

On the flip side, it is kind of a bummer that we need to promisify/denodeify node modules at all. Once you learn promises, you kind of want everything to return promises by default.

It is often considered that that comes at a cost. It doesn’t have to. As the authors of Promised-Mongo realised, and I realised while working on my latest project, you don’t have to choose between callbacks and promises.

You can easily continue to support callbacks in your library.

Say you have a function like this:

// var db = require("Promised-Mongo")

var promiseReturningUserDetails = function(userId){
  return db.users.find({id: userId});

This works great if the users of this function understand promises. But the truth is that many people do not. The good news is that it is easy to modify this function just enough to make it support callbacks.

var userDetails = function(userId, callback){
  var a = db.users.find({id: userId});
  if(typeof callback === 'function'){
    a.then(callback.bind(this, null)).catch(callback);
    return a;

And that’s it. The function now works with callbacks, but returns a Promise if no callback is provided. As long as you can figure out if a callback exists or not (you should be) you can always drop the same three lines at the end of your function, and make everything work.

It’s a simple elegant solution to a problem that shouldn’t exist. Promises and Callbacks can all live peacefully.


Now read this

Features CSS Needs

While the work on Houdini continues, I think it makes sense to prioritise a few simple features that would make life much easier for developers trying to build the most common things we need on the web. I have carefully chosen the... Continue →