后,别人回答,你说,你的问题是局部变量。看起来一个简单的方法是编写一个外部函数来包含这些局部变量,然后使用一堆命名的内部函数并按名称访问它们。这样,无论你需要链接多少个函数,你都只能嵌套两个深度。
这里是我的新手的使用时的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);
}
我一直在想,也许这将是可以使用实例变量创建一个对象,并使用这些实例变量来替代局部变量。但是现在我发现使用嵌套函数和局部变量的上述方法更简单,更易于理解。它需要一些时间来忘掉面向对象,它看起来:-)
所以这里是我的以前版本的对象和实例变量。
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编码 - 我只是花了几个小时就可以了。但也许有点抛光这种技术可以帮助?
所以,当你有10个异步功能,你有10个级别的缩进? – 2010-11-20 20:32:56
此链接可能会有所帮助。 http://stackoverflow.com/a/4631909/290340 – 2012-01-24 22:28:47
另一个问题:在'getSomeDate'和'getSomeOtherDate'之间插入另一个函数最终会改变许多行的缩进,这使得git历史难以阅读('git blame'甚至在此之后无用),并且在手动执行此操作时可能会产生错误 – 2014-12-30 02:57:45