После того, как другие ответили, вы заявили, что вашей проблемой являются локальные переменные.Кажется, что простой способ сделать это - написать одну внешнюю функцию, которая будет содержать эти локальные переменные, затем использовать группу именованных внутренних функций и обращаться к ним по имени.Таким образом, вы будете когда-либо вкладывать только две глубокие, независимо от того, сколько функций вам нужно соединить вместе.
Вот попытка моего новичка использовать модуль 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);
}
* 1014Я думал, что, возможно, можно будет создать объект с переменными экземпляра и использовать эти переменные экземпляра в качестве замены локальных переменных.Но теперь я обнаружил, что описанный выше подход с использованием вложенных функций и локальных переменных проще и понятнее.Кажется, требуется некоторое время, чтобы отключить 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);
}
Конечно, ничего из этого не является правильным JS с кодированием Node.js - я просто потратил паручасов на это.Но, может быть, с небольшой полировкой эта техника может помочь?