与Bluebird手动promisifying pg.connect

我想promisify node-postgres'pg.connect方法以及callback中提供的内部connection.query方法。

我可以将后者进行修改,但是我需要手动执行第一个(如果我在这里丢失了某些东西,请解释一下)。

事情是,我不确定这段代码是否正确或应该改进? 代码工作,我只是想知道,如果我使用蓝鸟的意思。

 // 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; }; 

抛出所有可怕的callback代码,然后在应用程序初始化的某个地方执行此操作:

 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); 

在后来的任何地方,你都可以使用pg模块,就像它被devise成使用promise一样:

 // 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(); }); }); 

到目前为止,有一些图书馆为你做这个工作:

  • pg-promise – PG的通用Promises / A +
  • Postgres的,蓝鸟
  • 胸径-PH
  • PG-蓝鸟

蓝鸟3的更新

pg.connectAsync(...).spread(function(connection, release) { ... })调用将不再起作用,因为bluebird的API已经改变了: http : //bluebirdjs.com/docs/new- in-bluebird-3.html#promisification-api-changes 。

问题是promisifyAll在蓝鸟3不处理多个参数默认情况下。 这会导致.spread()调用报告TypeError,如下所示:

 TypeError: expecting an array or an iterable object but got [object Null] 

为了解决这个问题,你可以明确地为connect / connectAsync启用多个参数。 在完成上面提到的所有事情之后,执行以下操作:

 ... pg.connectAsync = Promise.promisify(pg.connect, { multiArgs: true }); 

我build议稍微修改Petka Antonov解决scheme

 var Promise = require('bluebird'); var pg = require('pg'); Object.keys(pg).forEach(function (key) { var Cls = null; try { Cls = pg[key]; if (typeof Cls === 'function') { Promise.promisifyAll(Cls.prototype); Promise.promisifyAll(Cls); } } catch (e) { console.log(e); } }); Promise.promisifyAll(pg); 

这里'pg[key]封装在try-catch块中,因为当试图访问pg['native']时, pg[key]可能会重try-catch error