1

我一直在尝试将 bluebird 承诺与 pg 库一起使用,甚至发现了这篇文章,但遗憾的是,我对 StackOverflow 用户太陌生,无法直接在那里发表评论:Manually promisifying pg.connect with Bluebird

简而言之,在剪切和粘贴该代码后,我使用 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 文件,但无济于事。

4

3 回答 3

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 绑定与 C 绑定(libpq)和手动承诺。

于 2014-07-02T02:19:02.690 回答
2

如果您想充分利用Promises/A+架构,同时将PG 库Bluebird结合在一起,请尝试pg-promise

如果使用得当,手动承诺几乎不会给数据库带来任何好处,例如连接管理、自动事务等。

只是为了给您一个想法,这是使用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
  • 检查交易是否成功关闭;
  • 释放连接回池;
  • 返回结果以供进一步处理;

现在,考虑嵌套事务:)

于 2015-04-14T16:56:48.033 回答
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]运行errorpg['native']

于 2016-02-25T15:29:23.767 回答