3

实现此代码时(直接取自https://github.com/brianc/node-postgres的示例):

var pg = require('pg'); 

var conString = "tcp://postgres:1234@localhost/postgres";

pg.connect(conString, function(err, client) {
  client.query("SELECT NOW() as when", function(err, result) {
      console.log("Row count: %d",result.rows.length);  // 1
      console.log("Current year: %d", result.rows[0].when.getFullYear());
      //Code halts here
  });
});

在最后一个之后console.log,节点挂起。我认为这是因为异步性质,我怀疑在这一点上,应该调用一个回调函数。

我有两个问题:

  1. 我的想法正确吗?
  2. 如果我的想法是正确的,那么机制是如何工作的。我知道 NodeJS 正在使用一个事件循环,但是是什么让这个事件循环在这一点上停止了?
4

1 回答 1

6

它似乎挂起,因为与 Postgres 的连接仍处于打开状态。直到它关闭或“结束”......

client.end(); // Code halts here

节点将继续空闲等待将另一个事件添加到队列中。


  1. 不完全的。这是 Node 的细节node-postgres及其依赖关系,而不是 Node 或其“异步性质”的一般细节。

  2. 空闲是由于并记录了使用的generic-pool模块node-postgres

    如果您要关闭一个长期存在的进程,您可能会注意到节点未能退出 30 秒左右。这是 idleTimeoutMillis 行为的副作用——池在事件循环队列中注册了一个 setTimeout() 调用,因此节点不会终止,直到所有资源都超时,并且池停止尝试管理它们。

    而且,正如它在Draining下解释的那样:

    如果您知道想要在达到超时之前终止池中的所有资源,您可以destroyAllNow()结合使用drain()

    pool.drain(function() {
        pool.destroyAllNow();
    });
    

    调用的一个副作用drain()是后续调用acquire()将引发错误。

    如果您打算在串行应用程序结束时退出,例如单元测试或您给定的代码段,那么就是并且pg.end()肯定可以完成的事情。

于 2012-11-20T04:43:30.140 回答