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、ノードがハングします。これは非同期の性質によるものだと思います。現時点では、コールバック関数を呼び出す必要があると思います。

2 つの質問があります。

  1. 私の考えは正しいですか?
  2. 私の考えが正しければ、メカニズムはどのように機能するのでしょうか。NodeJS がイベント ループを使用していることは知っていますが、この時点でこのイベント ループを停止させているのは何ですか?
4

1 に答える 1

6

Postgres への接続がまだ開いているため、ハングしているように見えます。閉鎖されるまで、または「終了」するまで...

client.end(); // Code halts here

ノードは、別のイベントがキューに追加されるまでアイドル状態で待機し続けます。


  1. そうではありません。これは、node-postgresNode やその「非同期性」の詳細ではなく、その依存関係の詳細です。

  2. アイドリングは、以下を使用するモジュールによるものであり、文書化されています。generic-poolnode-postgres

    存続期間の長いプロセスをシャットダウンしている場合、ノードが 30 秒ほど終了しないことに気付くかもしれません。これは、idleTimeoutMillis 動作の副作用です。プールには、イベント ループ キューにある setTimeout() 呼び出しが登録されているため、すべてのリソースがタイムアウトするまでノードは終了せず、プ​​ールはそれらの管理を停止します。

    そして、Drainingで説明されているように:

    タイムアウトに達する前にプール内のすべてのリソースを終了したいことがわかっている場合は、次のものdestroyAllNow()と組み合わせて使用​​できdrain()ます。

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

    呼び出しの副作用の 1 つdrain()は、後続の呼び出しでacquire()エラーがスローされることです。

    ユニットテストや特定のスニペットなど、シリアルアプリケーションの最後で終了することが意図されている場合、これはpg.end()をするか、そして確実に行うことできます。

于 2012-11-20T04:43:30.140 に答える