後,別人回答,你說,你的問題是局部變量。看起來一個簡單的方法是編寫一個外部函數來包含這些局部變量,然後使用一堆命名的內部函數並按名稱訪問它們。這樣,無論你需要鏈接多少個函數,你都只能嵌套兩個深度。
這裏是我的新手的使用時的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