使用postgres作为NodeJS中的示例的异步调用

Bar*_*eyn 3 node.js

实现此代码时(直接从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
  });
});
Run Code Online (Sandbox Code Playgroud)

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

我有两个问题:

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

Jon*_*ski 6

它似乎挂起,因为与Postgres的连接仍然是打开的.直到它关闭或"结束"......

client.end(); // Code halts here
Run Code Online (Sandbox Code Playgroud)

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


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

  2. 空转是由于和记录了generic-pool模块node-postgres使用:

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

    而且,正如它在排水中所解释的那样:

    如果您知道希望在达到超时之前终止池中的所有资源,则可以destroyAllNow()drain()以下内容一起使用:

    pool.drain(function() {
        pool.destroyAllNow();
    });
    
    Run Code Online (Sandbox Code Playgroud)

    调用的一个副作用drain()是后续调用acquire()将抛出一个错误.

    这是什么pg.end()可以肯定做,如果你的目的是在串行应用月底退出,比如单元测试或您给出片段.