Create a Promise Wrapper For a Standand Node Callback Method

Update: Prefer const over let

JavaScript Promises are the future, and a great pattern for doing asynchronous javascript code (allegedly async await is an awesome way to do async javascript as well, but I’m not there yet). There are great APIs for working with promises, and many standard libraries for working with Promises.

Unfortunately not all libraries support promises. Fortunately it isn’t hard to wrap a standard javascript callback pattern api in a promisified version.

The Node.js way is to have callbacks with an error first callback. These are apis which are passed a callback function with the signature function(error, success);. For a good description see this decent blog post The Node.js Way – Understanding Error-First Callbacks.

The classic example they provide is read file:

fs.readFile('/foo.txt', function(error, data) {
  // TODO: Error Handling Still Needed!
  console.log(data);
});

To convert this to a promise, create a new promise object, which calls reject with the error, and resolve with the data. If this is wrapped in a function, you’ll end up with a nice promisified readFile as per the following:

const fs=require('fs');

function readFilePromise(fileName) {
  return new Promise(function(resolve, reject){
    fs.readFile(fileName, function(err, data){
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}

For extra cool kid points, use arrow functions:

const fs=require('fs');

const readFilePromise = fileName => {
  new Promise((resolve, reject) => {
    fs.readFile(fileName, (err, data)=> {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    })
  })
}

or to shrink it a little bit more:

const fs=require('fs');

const readFilePromise = fileName => {
  return new Promise((resolve, reject) => {fs.readFile(fileName, (err, data)=> {err ? reject(err) : resolve(data)})})
}

or to go a bit crazy with the inlining, and make your javascript look almost like haskell 🙂

const fs=require('fs');

const readFilePromise = fileName => new Promise((res, rej) => fs.readFile(fileName, (e, d) => e ? rej(e) : res(d)));

So it’s easy to see that any asynchronous node callback style api can be wrapped in a promise api with 10 lines of readable code, or 1 line of terse javascript.

One thought on “Create a Promise Wrapper For a Standand Node Callback Method

  1. Pingback: Creating a Deliverable HTML Email on AWS Lambda with SES | Rob's Creek

Leave a Reply

Your email address will not be published. Required fields are marked *