Search code examples
node.jspromisebluebirdnode-postgres

Manually promisifying pg.connect with Bluebird


I want to promisify node-postgres' pg.connect method along with the inner connection.query method provided in the callback.

I can .promisify the latter, but I need to implement the first one manually (if I'm missing something here, please explain).

The thing is, I'm not sure if this code is correct or should be improved? The code is working, I just want to know if I'm using Bluebird as meant.

// aliases
var asPromise = Promise.promisify;

// save reference to original method
var connect = pg.connect.bind(pg);

// promisify method
pg.connect = function (data) {
  var deferred = Promise.defer();

  connect(data, function promisify(err, connection, release) {
    if (err) return deferred.reject(err);

    // promisify query factory
    connection.query = asPromise(connection.query, connection);

    // resolve promised connection
    deferred.resolve([connection,release]);
  });

  return deferred.promise;
};

Solution

  • Throw all that horrible callback code away, then do this somewhere in your application initialization:

    var pg = require("pg");
    var Promise = require("bluebird");
    
    Object.keys(pg).forEach(function(key) {
        var Class = pg[key];
        if (typeof Class === "function") {
            Promise.promisifyAll(Class.prototype);
            Promise.promisifyAll(Class);
        }
    })
    Promise.promisifyAll(pg);
    

    Later in anywhere you can use the pg module as if it was designed to use promises to begin with:

    // Later
    // Don't even need to require bluebird here
    var pg = require("pg");
    // Note how it's the pg API but with *Async suffix
    pg.connectAsync(...).spread(function(connection, release) {
         return connection.queryAsync("...")
             .then(function(result) {
                console.log("rows", result.rows);
             })
             .finally(function() {
                // Creating a superfluous anonymous function cos I am
                // unsure of your JS skill level
                release();
             });
    });