他の人が答えた後、あなたの問題はローカル変数であると述べました。これを行う簡単な方法は、これらのローカル変数を含む1つの外部関数を記述し、名前付きの内部関数の束を使用して、名前でそれらにアクセスすることです。この方法では、チェーンする必要のある関数の数に関係なく、2つだけの深さまでネストできます。
初心者がmysql
Node.jsモジュールをネストして使用する試みは次のとおりです。
function with_connection(sql, bindings, cb) {
pool.getConnection(function(err, conn) {
if (err) {
console.log("Error in with_connection (getConnection): " + JSON.stringify(err));
cb(true);
return;
}
conn.query(sql, bindings, function(err, results) {
if (err) {
console.log("Error in with_connection (query): " + JSON.stringify(err));
cb(true);
return;
}
console.log("with_connection results: " + JSON.stringify(results));
cb(false, results);
});
});
}
以下は、名前付き内部関数を使用した書き換えです。外部関数with_connection
は、ローカル変数のホルダーとしても使用できます。(ここでは、同様に機能するパラメーター、、を用意していますがsql
、bindings
でcb
追加のローカル変数をいくつか定義するだけwith_connection
です。)
function with_connection(sql, bindings, cb) {
function getConnectionCb(err, conn) {
if (err) {
console.log("Error in with_connection/getConnectionCb: " + JSON.stringify(err));
cb(true);
return;
}
conn.query(sql, bindings, queryCb);
}
function queryCb(err, results) {
if (err) {
console.log("Error in with_connection/queryCb: " + JSON.stringify(err));
cb(true);
return;
}
cb(false, results);
}
pool.getConnection(getConnectionCb);
}
インスタンス変数を持つオブジェクトを作成し、これらのインスタンス変数をローカル変数の代わりとして使用することはおそらく可能だろうと私は考えていました。しかし、今度は、ネストされた関数とローカル変数を使用する上記のアプローチが単純で理解しやすいことに気づきました。OOの学習を解除するには時間がかかります。
これが、オブジェクトとインスタンス変数を含む私の以前のバージョンです。
function DbConnection(sql, bindings, cb) {
this.sql = sql;
this.bindings = bindings;
this.cb = cb;
}
DbConnection.prototype.getConnection = function(err, conn) {
var self = this;
if (err) {
console.log("Error in DbConnection.getConnection: " + JSON.stringify(err));
this.cb(true);
return;
}
conn.query(this.sql, this.bindings, function(err, results) { self.query(err, results); });
}
DbConnection.prototype.query = function(err, results) {
var self = this;
if (err) {
console.log("Error in DbConnection.query: " + JSON.stringify(err));
self.cb(true);
return;
}
console.log("DbConnection results: " + JSON.stringify(results));
self.cb(false, results);
}
function with_connection(sql, bindings, cb) {
var dbc = new DbConnection(sql, bindings, cb);
pool.getConnection(function (err, conn) { dbc.getConnection(err, conn); });
}
それはbind
いくつかの利点に使用できることがわかりました。これにより、自分が作成した、メソッド呼び出しに転送する以外は何もしない、やや醜い匿名関数を取り除くことができます。の値が間違っているため、メソッドを直接渡すことができませんでしたthis
。しかし、bind
では、必要な値を指定できますthis
。
function DbConnection(sql, bindings, cb) {
this.sql = sql;
this.bindings = bindings;
this.cb = cb;
}
DbConnection.prototype.getConnection = function(err, conn) {
var f = this.query.bind(this);
if (err) {
console.log("Error in DbConnection.getConnection: " + JSON.stringify(err));
this.cb(true);
return;
}
conn.query(this.sql, this.bindings, f);
}
DbConnection.prototype.query = function(err, results) {
if (err) {
console.log("Error in DbConnection.query: " + JSON.stringify(err));
this.cb(true);
return;
}
console.log("DbConnection results: " + JSON.stringify(results));
this.cb(false, results);
}
// Get a connection from the pool, execute `sql` in it
// with the given `bindings`. Invoke `cb(true)` on error,
// invoke `cb(false, results)` on success. Here,
// `results` is an array of results from the query.
function with_connection(sql, bindings, cb) {
var dbc = new DbConnection(sql, bindings, cb);
var f = dbc.getConnection.bind(dbc);
pool.getConnection(f);
}
もちろん、これはNode.jsコーディングを使用した適切なJSではありません-私はそれに数時間費やしただけです。しかし、おそらく少し磨くことで、このテクニックは役に立ちますか?