【问题标题】:nodejs, postgres, and bluebirdnodejs、postgres 和 bluebird
【发布时间】:2014-08-20 12:01:32
【问题描述】:

我一直在尝试在 pg 库中使用 bluebird Promise,甚至发现了这篇文章,但遗憾的是,我对 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:

相关sn-p:

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 文件,但无济于事。

【问题讨论】:

    标签: node.js postgresql bluebird


    【解决方案1】:

    事实证明,在使用 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) 和手动承诺。

    【讨论】:

      【解决方案2】:

      如果您想充分利用Promises/A+ 架构,同时将PG libraryBluebird 结合在一起,请尝试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
      • 检查交易是否成功关闭;
      • 释放连接回池;
      • 返回结果以供进一步处理;

      现在,考虑嵌套事务:)

      【讨论】:

        【解决方案3】:

        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] 可以在尝试访问pg['native'] 时重新运行error

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-07
          • 2016-05-21
          • 2015-11-13
          • 1970-01-01
          相关资源
          最近更新 更多