Setelah yang lain merespons, Anda menyatakan bahwa masalah Anda adalah variabel lokal. Tampaknya cara yang mudah untuk melakukan ini adalah menulis satu fungsi luar untuk memuat variabel-variabel lokal, kemudian menggunakan sekelompok fungsi dalam bernama dan mengaksesnya dengan nama. Dengan cara ini, Anda hanya akan memiliki dua sarang, terlepas dari berapa banyak fungsi yang Anda butuhkan untuk rantai bersama.
Ini adalah usaha pemula saya untuk menggunakan mysql
modul Node.js dengan nesting:
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);
});
});
}
Berikut ini adalah penulisan ulang menggunakan fungsi dalam bernama. Fungsi luar with_connection
juga dapat digunakan sebagai penahan untuk variabel lokal. (Di sini, saya punya parameter sql
, bindings
,cb
yang bertindak dengan cara yang sama, tetapi Anda hanya dapat mendefinisikan beberapa variabel lokal tambahan di 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);
}
Saya telah berpikir bahwa mungkin akan mungkin untuk membuat objek dengan variabel instan, dan menggunakan variabel instan ini sebagai pengganti variabel lokal. Tapi sekarang saya menemukan bahwa pendekatan di atas menggunakan fungsi bersarang dan variabel lokal lebih sederhana dan lebih mudah dipahami. Butuh waktu untuk menghapus OO, sepertinya :-)
Jadi di sini adalah versi saya sebelumnya dengan variabel objek dan instance.
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); });
}
Ternyata itu bind
bisa digunakan untuk beberapa keuntungan. Ini memungkinkan saya untuk menyingkirkan fungsi anonim yang agak jelek yang saya buat yang tidak melakukan banyak hal, kecuali untuk meneruskan diri ke pemanggilan metode. Saya tidak bisa lulus metode secara langsung karena akan terlibat dengan nilai yang salah this
. Tetapi dengan bind
, saya dapat menentukan nilai this
yang saya inginkan.
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);
}
Tentu saja, semua ini bukan JS yang sesuai dengan Node.js coding - Saya hanya menghabiskan beberapa jam untuk itu. Tapi mungkin dengan sedikit memoles teknik ini bisa membantu?