在 node.js 中关闭 postgres (pg) 客户端连接

Closing postgres (pg) client connection in node.js

我有一个脚本,我想 运行 在节点中定期执行。该脚本没有终止和退出。我怀疑这是因为我的数据库客户端仍然打开。

var client = new pg.Client(conString);
client.connect();

function registerBundle (innerHash, outterHash) {
    // some stuff here
}

var query = client.query("SELECT id, chain FROM mytable where \
    state_ready = true and transaction_id='' ");

query.on('row', function(row) {
    var chain = row['chain'];
    var pg_record = row['id'];
    console.log(pg_record);
    var innerHash = "something";
    var outerHash = "something else";
    var registrar = registerBundle(innerHash, outerHash);

    var update = client.query('UPDATE mytable SET transaction_id = ::text \
    where id=::int', [transactionHash, pg_record]);
    console.log(chain);
});

如果我包含以下内容,客户端连接会在更新触发之前关闭。

query.on('end', function() {
    client.end();
});

我无法使用 setTimeout 或任何其他此类机制,因为我不知道等待 registerBundle 函数完成需要多长时间。另外我认为 query.on('end' 将在更新完成时触发。不确定如何测试。

我的问题是,我需要按顺序触发。

在 python/php 的世界里看起来很简单,但在我的 javascript 的世界里就分崩离析了。

pg-promise这样的promise-based界面是要走的路:

var bluebird = require('bluebird');
var pgp = require('pg-promise')({
    promiseLib: bluebird
});
var db = pgp(/*connection details*/);

db.tx(t => {
    // BEGIN executed
    return t.map('SELECT id, chain FROM mytable where state_ready =  and transaction_id = ', [true, 123], a => {
        var chain = data.chain;
        var pg_record = data.id;
        return t.none('UPDATE mytable SET transaction_id = ::text where id=::int', [transactionHash, pg_record]);
    }).then(t.batch); // settling all internal queries
})
    .then(data => {
        // success, COMMIT executed
    })
    .catch(error => {
        // error, ROLLBACK executed
    })
    .finally(pgp.end); // shuts down the connection pool

上面的例子完全按照你的要求做了,而且它使用了一个事务。但实际上,出于性能原因,您会希望在一个查询中完成所有操作;)

参见more examples