6

我想承诺 node-postgres 的方法以及回调中提供pg.connect的内部方法。connection.query

我可以.promisify后者,但我需要手动实现第一个(如果我在这里遗漏了什么,请解释)。

问题是,我不确定这段代码是否正确或应该改进?该代码正在运行,我只想知道我是否按原意使用 Bluebird。

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

4 回答 4

4

扔掉所有可怕的回调代码,然后在你的应用程序初始化的某个地方执行此操作:

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 模块,就好像它被设计为使用 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();
         });
});
于 2014-05-27T06:38:51.637 回答
4

到目前为止,有许多库可以为您执行此操作:

于 2014-11-05T14:06:34.497 回答
3

蓝鸟 3 更新

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

问题是promisifyAllbluebird 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 });
于 2016-03-01T11:50:58.223 回答
0

我建议稍微修改一下 Petka Antonov 解决方案

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:31:31.777 回答