在node.js中closurespostgres(pg)客户端连接

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

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 = $1::text \ where id=$2::int', [transactionHash, pg_record]); console.log(chain); }); 

如果我包含以下内容,客户端连接将在更新有时间之前closures。

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

我不能使用setTimeout或任何其他这样的机制,因为我不知道等待registerBundle函数完成多久。 此外,我认为query.on('结束'将更新完成时触发。不知道如何testing这个。

我的问题是,我需要按顺序开火。

  • 查询数据库
  • 处理每一行(query.on
  • 用从registerBundle返回的值更新每一行
  • 当所有的行已经被处理时closures数据库客户端/连接。
  • 终止脚本并退出节点

似乎从Python / PHP的世界相当简单,但在我的JavaScript世界崩溃。

像pg-promise这样的基于承诺的界面是要走的路:

 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 = $1 and transaction_id = $2', [true, 123], a => { var chain = data.chain; var pg_record = data.id; return t.none('UPDATE mytable SET transaction_id = $1::text where id=$2::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 

上面的例子完全是你所要求的,再加上它使用了一个事务。 但是实际上,由于性能方面的原因,你会想在一个查询中完成所有操作;)

看更多的例子 。