2014-06-30 88 views
1

我一直在尝试使用蓝鸟承诺与PG库,甚至发现这个职位,但可悲的是,我太新出现StackOverflow用户只需直接评论有:Manually promisifying pg.connect with Bluebird的NodeJS,Postgres的,和蓝鸟

简而言之,在做了剪切和粘贴代码之后,我用蓝鸟Promisfy函数试过的所有东西都没有引入任何查询构造函数,也许我在尝试中滥用ClientAsync函数,但希望这是一个快速和容易的帮助,因为我尝试的一切结果的一些变化:

Possibly unhandled TypeError: Object function (err) { 
     if(err) { 
     pool.destroy(client); 
     } else { 
     pool.release(client); 
     } 
    } has no method 'queryAsync' 

我倾销PromisfyA LL函数的结果,果然queryAsync不存在:

相关片段:

Client: { [Function] Query: { [Function] super_: [Object] } }, 
Query: 
    { [Function] 
    super_: { [Function: EventEmitter] listenerCount: [Function] } }, 
pools: 
    { all: {}, 
    Client: { [Function] Query: [Object] }, 
    getOrCreate: [Function] }, 
Connection: 
{ [Function] 
    super_: { [Function: EventEmitter] listenerCount: [Function] } }, 
types: 
{ getTypeParser: [Function], 
    setTypeParser: [Function], 
    arrayParser: { create: [Function] } }, 
ClientAsync: { [Function: ClientAsync] __isPromisified__: true }, 
endAsync: { [Function: endAsync] __isPromisified__: true }, 
connectAsync: { [Function: connectAsync] __isPromisified__: true }, 
cancelAsync: { [Function: cancelAsync] __isPromisified__: true }, 
setMaxListenersAsync: { [Function: setMaxListenersAsync] __isPromisified__: true }, 
emitAsync: { [Function: emitAsync] __isPromisified__: true }, 
addListenerAsync: { [Function: addListenerAsync] __isPromisified__: true }, 
onAsync: { [Function: onAsync] __isPromisified__: true }, 
onceAsync: { [Function: onceAsync] __isPromisified__: true }, 
removeListenerAsync: { [Function: removeListenerAsync] __isPromisified__: true }, 
removeAllListenersAsync: { [Function: removeAllListenersAsync] __isPromisified__: true }, 
listenersAsync: { [Function: listenersAsync] __isPromisified__: true } } 

它找到相关功能的解析,但不promisfy查询:没有人知道我可以麻烦通过ClientAsync执行SQL查询的更多步骤或潜在语法?我试图从bluebird github页面上的信息手动添加pg query.js文件,但无济于事。

回答

3

事实证明,使用Promisfy时,这是Javascript与本地绑定库的区别。

var pg = require('pg'); 
var Promise = require('bluebird'); 

var db = Promise.promisifyAll(pg); 

var connectionString = "postgres://node:[email protected]:5432/postgres"; 

db.connectAsync("postgres://node:[email protected]:5432/postgres").spread(function(connection, release) { 
    return connection.queryAsync("select * from howdy") 
    .then(function(result) { 
     console.log("rows", result.rows); 
    }) 
    .finally(function() { 
     release(); 
    }); 
}); 

工程,而这样的:

var pg = require('pg').native; 
var Promise = require('bluebird'); 

中断与难看的错误消息。

我想我需要做一些基准测试,最终的各个选项(蓝鸟W/promisfy和JS-绑定相对于C绑定(的libpq)和手动承诺之间。

+0

什么难看的错误信息? – Flimzy

2

如果你想获得最出Promises/A+架构,同时加入PG libraryBluebird在一起,尝试pg-promise

手册promisification会给几乎没有任何好处,如果使用得当,像连接管理,自动交易等

,承诺可以提供,否则到数据库

只给你一个想法,这里有一个完整的交易看起来如何与pg-promise,很好地隐藏两个连接和交易细节:

db.tx(function() { 
    return this.batch([ 
     this.query("update users set active=$1 where id=$2", [true, 123]), 
     this.query("insert into audit(status, id) values($1, $2)", ['active', 123]) 
    ]); 
}) 
    .then(function (data) { 
     // success; 
    }, function (reason) { 
     // error; 
    }); 

并通过手动promisified版本非常相同的逻辑将是很多次长,更复杂。实际上,您仍然需要执行以下所有操作:

  • 打开连接;
  • 检查连接是否成功;
  • 执行BEGIN命令;
  • 执行查询序列;
  • 检查您的查询是否成功;
  • 根据您的查询成功执行COMMITROLLBACK;
  • 检查交易是否成功关闭;
  • 释放连接回池;
  • 返回结果以作进一步处理;

现在,考虑嵌套事务:)

0

bluebird的创造者回答了相关的问题在这里Manually promisifying pg.connect with Bluebird。 我修改了这个解决方案。

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[key]可以retrun error当试图访问pg['native']