nodejs,postgres和bluebird

时间:2014-06-30 07:09:25

标签: node.js postgresql bluebird

我一直试图在pg库中使用bluebird promises,甚至发现了这篇文章,但遗憾的是我太过新的StackOverflow用户只是直接在那里发表评论:Manually promisifying pg.connect with Bluebird

简单地说,在对该代码进行剪切和粘贴后,我尝试使用蓝鸟Promisfy函数的所有内容都不会引入任何查询构造函数,也许我误用了ClientAsync我尝试的功能,但我希望这是一个快速简单的帮助,因为我尝试的一切导致一些变化:

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

我转储了PromisfyAll函数结果,并确定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 } }

它在解析中找到了相关的功能,但并不满足查询:有没有人知道如何进一步解决这个问题或者使用ClientAsync执行SQL查询的潜在语法?我试图从Bluebird github页面上的信息手动添加pg query.js文件,但无济于事。

3 个答案:

答案 0 :(得分:3)

当使用Promisfy时,Javascript与本机绑定库的区别很明显。

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

var db = Promise.promisifyAll(pg);

var connectionString = "postgres://node:node@localhost:5432/postgres";

db.connectAsync("postgres://node:node@localhost: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');

打破丑陋的错误消息。

我想我最终需要在各种选项之间做一些基准测试(bluebird w / promisfy和JS-bindings与C-bindings(libpq)和手动承诺。

答案 1 :(得分: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;
    });

通过手动宣传版本的相同逻辑将会长很多倍,而且要复杂得多。事实上,您仍然需要执行以下所有操作:

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

现在,考虑嵌套事务:)

答案 2 :(得分: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]在尝试访问error时可以重新pg['native']