Dopo che gli altri hanno risposto, hai dichiarato che il tuo problema erano variabili locali. Sembra un modo semplice per farlo è scrivere una funzione esterna per contenere quelle variabili locali, quindi utilizzare un gruppo di funzioni interne denominate e accedervi per nome. In questo modo, ne anniderai solo due in profondità, indipendentemente da quante funzioni devi mettere insieme.
Ecco il tentativo del mio principiante di utilizzare il mysql
modulo Node.js con annidamento:
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);
});
});
}
Di seguito è una riscrittura che utilizza le funzioni interne denominate. La funzione esterna with_connection
può essere utilizzata anche come supporto per le variabili locali. (Qui, ho i parametri sql
, bindings
, cb
che agiscono in modo simile, ma si può solo definire alcune variabili locali addizionali 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);
}
Pensavo che forse sarebbe stato possibile creare un oggetto con variabili di istanza e utilizzare queste variabili di istanza in sostituzione delle variabili locali. Ma ora trovo che l'approccio sopra usando funzioni nidificate e variabili locali è più semplice e più facile da capire. Ci vuole del tempo per disimparare OO, sembra :-)
Quindi ecco la mia versione precedente con un oggetto e variabili di istanza.
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); });
}
Si scopre che bind
può essere usato con qualche vantaggio. Mi permette di sbarazzarmi delle funzioni anonime un po 'brutte che ho creato che non hanno fatto molto, tranne che per inoltrarsi a una chiamata di metodo. Non ho potuto passare direttamente il metodo perché sarebbe stato coinvolto con il valore errato di this
. Ma con bind
, posso specificare il valore this
che desidero.
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);
}
Ovviamente, niente di tutto questo è corretto JS con la codifica Node.js - ho appena trascorso un paio d'ore su di esso. Ma forse con un po 'di lucidatura questa tecnica può aiutare?