Diğerleri yanıtladıktan sonra, sorunun yerel değişkenler olduğunu söylediniz. Bunu yapmanın kolay bir yolu, bu yerel değişkenleri içermek için bir dış fonksiyon yazmak, daha sonra adlandırılmış iç fonksiyonlar kullanmak ve isimlere erişmek. Bu şekilde, birlikte zincirlemeniz gereken fonksiyonlardan bağımsız olarak, yalnızca iki derin yuva yaparsınız.
Yeni başlayanımın mysql
Node.js modülünü iç içe yerleştirme ile kullanma girişimi :
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);
});
});
}
Aşağıda, adlandırılmış iç işlevler kullanılarak bir yeniden yazma yer almaktadır. Dış fonksiyon with_connection
yerel değişkenler için de tutucu olarak kullanılabilir. (İşte, parametreleri var sql
, bindings
, cb
benzer şekilde bu eylemi, ama sadece bazı ek yerel değişkenler tanımlayabilirsiniz 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);
}
Belki de örnek değişkenleri olan bir nesne yapmak ve bu örnek değişkenleri yerel değişkenlerin yerine kullanmak mümkün olabileceğini düşünüyordum. Ancak şimdi, iç içe geçmiş işlevleri ve yerel değişkenleri kullanan yukarıdaki yaklaşımın daha basit ve anlaşılması daha kolay olduğunu düşünüyorum. OO'nun öğrenilmesi biraz zaman alıyor, öyle görünüyor :-)
İşte bir nesne ve örnek değişkenleri ile önceki sürümüm.
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
Bazı avantajlar için kullanılabileceği ortaya çıktı . Kendilerini bir yöntem çağrısına iletmek dışında, hiçbir şey yapmayan, biraz çirkin anonim işlevlerden kurtulmama izin veriyor. Yöntemi doğrudan geçemedim çünkü yanlış değerine karışmış olurdu this
. Ama ile istediğim bind
değeri belirtebilirim 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);
}
Tabii ki, bunların hiçbiri Node.js kodlaması ile uygun JS değil - sadece birkaç saat geçirdim. Ama belki biraz parlatma ile bu teknik yardımcı olabilir?