3

node-postgresは次のように述べています。

node-postgres は、「イベント エミッター」スタイルの API と「コールバック」スタイルの両方をサポートしています。コールバック スタイルはより簡潔で一般的に好まれますが、イベント API が便利です。それらは混合して一致させることができます。

イベント エミッター API を使用すると、次のことができます。

var db = new pg.Client("insert-postgres-connection-info");
db.connect();

そして、 を使用dbして、Web アプリ全体でクエリを実行できますdb.query('sql statement here')。コールバック スタイルでは、クエリを実行するたびに次のようにします。

pg.connect(conString, function(err, client) {
  client.query("sql statement", function(err, result) {
    // do stuff
  });
});

だから私の質問は、コールバックスタイルを使用することが「一般的に好まれる」のはなぜですか? データベースで何かをするたびに接続を開くのは非効率的ではありませんか? コールバック スタイルを使用する利点は何ですか?

編集

「コールバック スタイル」とは何を意味しているのか誤解されているかもしれませんが (冗談ではありません。私の JavaScript はあまり強力ではありません)、私の質問は接続方法に関するものです。以下がコールバック スタイルの接続方法であると仮定しました。

// Simple, using built-in client pool

var pg = require('pg'); 
//or native libpq bindings
//var pg = require('pg').native

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

//error handling omitted
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.getYear());
  });
});

以下は、EventEmitter API の接続方法です。

// Evented api
var pg = require('pg'); //native libpq bindings = `var pg = require('pg').native`
var conString = "tcp://postgres:1234@localhost/postgres";

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

ここで用語が混同されているだけなら、私の質問はまだ残っています。pg.connect(do queries)使用するたびに新しい接続を開きます(そうではありませんか?)一方、

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

接続を開き、client必要に応じてクエリを実行できるようにしますか?

4

2 に答える 2

8

EventEmitter スタイルは、このタイプのものに適しています。

var query = client.query("SELECT * FROM beatles WHERE name = $1", ['John']);
query.on('row', function(row) {
  console.log(row);
  console.log("Beatle name: %s", row.name); //Beatle name: John
  console.log("Beatle birth year: %d", row.birthday.getYear()); //dates are returned as javascript dates
  console.log("Beatle height: %d' %d\"", Math.floor(row.height/12), row.height%12); //integers are returned as javascript ints
});

組み合わせることで、次のことができるはずです。

// Connect using EE style
var client = new pg.Client(conString);
client.connect();

// Query using callback style
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.getYear());
});

コールバック スタイルを使用する場合でも、クエリを実行するたびに接続を開くわけではないことに注意してください。ほとんどの場合、アプリケーションの起動時に接続を開き、それをずっと使用します。

于 2012-08-17T20:05:12.887 に答える
5

長所と短所があり、どちらを選択するかはユースケースによって異なります。

使用例 1: 結果セットを行ごとにクライアントに返します。

データベースから出てくるのとほぼ同じ方法で (行ごとに) データをクライアントに返す場合は、イベント エミッター スタイルを使用して待機時間を短縮できます。ここでは、待機時間をリクエスト発行間の時間として定義します。最初の行を受け取ります。代わりにコールバック スタイルを使用すると、レイテンシが増加します。

ユース ケース 2: 結果セット全体に基づいて、階層データ構造 (JSON など) を返します。

JSON などの階層データ構造でクライアントにデータを返す場合 (結果セットが階層のフラットな表現である場合に帯域幅を節約するために行う)、コールバック スタイルを使用する必要があります。すべての行を受け取るまで何も返さないでください。イベント エミッター スタイルを使用して行を蓄積することもできます (node-postgres はそのようなメカニズムを提供するため、クエリによって部分的に構築された結果のマップを維持する必要はありません)。最後の行を受け取るまで、すべての結果を返します。

ユース ケース 3: 階層データ構造の配列を返します。

階層データ構造の配列を返す場合、コールバック スタイルを使用すると、一度に多数の行を処理する必要があります。多くのクライアントにサービスを提供するスレッドが 1 つしかないため、これはかなりの時間ブロックされますが、これは良くありません。そのため、行アキュムレータでイベント エミッタ スタイルを使用する必要があります。結果セットは、特定のフィールドの値の変化を検出したときに、現在の行が返される新しい結果の先頭を表し、これまでに蓄積されたすべての結果が完全な結果を表し、変換できるようになるように並べ替える必要があります。階層化され、クライアントに返されます。

于 2013-02-03T11:44:19.247 に答える