Nachdem die anderen geantwortet hatten, gaben Sie an, dass Ihr Problem lokale Variablen waren. Es scheint eine einfache Möglichkeit zu sein, eine äußere Funktion zu schreiben, die diese lokalen Variablen enthält, dann eine Reihe benannter innerer Funktionen zu verwenden und namentlich darauf zuzugreifen. Auf diese Weise verschachteln Sie immer nur zwei tief, unabhängig davon, wie viele Funktionen Sie miteinander verketten müssen.
Hier ist der Versuch meines Neulings, das mysql
Node.js-Modul mit Verschachtelung zu verwenden:
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);
});
});
}
Das Folgende ist ein Umschreiben unter Verwendung benannter innerer Funktionen. Die äußere Funktion with_connection
kann auch als Halter für lokale Variablen verwendet werden. (Hier habe ich die Parameter bekam sql
, bindings
, cb
dass die Handlung in einer ähnlichen Art und Weise, aber Sie können nur einige zusätzliche lokale Variablen in definieren 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);
}
Ich hatte gedacht, dass es vielleicht möglich sein würde, ein Objekt mit Instanzvariablen zu erstellen und diese Instanzvariablen als Ersatz für die lokalen Variablen zu verwenden. Aber jetzt finde ich, dass der obige Ansatz mit verschachtelten Funktionen und lokalen Variablen einfacher und verständlicher ist. Es scheint einige Zeit zu dauern, OO zu verlernen, wie es scheint :-)
Hier ist meine vorherige Version mit Objekt- und Instanzvariablen.
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); });
}
Es stellt sich heraus, dass bind
dies zu einem gewissen Vorteil genutzt werden kann. Es ermöglicht mir, die etwas hässlichen anonymen Funktionen, die ich erstellt habe und die nicht viel bewirkt haben, loszuwerden, außer mich selbst an einen Methodenaufruf weiterzuleiten. Ich konnte die Methode nicht direkt übergeben, da sie mit dem falschen Wert von verbunden gewesen wäre this
. Aber mit bind
kann ich den Wert angeben, den this
ich möchte.
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);
}
Natürlich ist nichts davon richtig mit JS mit Node.js Codierung - ich habe nur ein paar Stunden damit verbracht. Aber vielleicht kann diese Technik mit ein wenig Polieren helfen?