Sau khi những người khác trả lời, bạn nói rằng vấn đề của bạn là các biến cục bộ. Có vẻ như một cách dễ dàng để làm điều này là viết một hàm ngoài để chứa các biến cục bộ đó, sau đó sử dụng một loạt các hàm bên trong có tên và truy cập chúng theo tên. Bằng cách này, bạn sẽ chỉ bao giờ lồng hai cái sâu, bất kể bạn cần bao nhiêu chức năng để liên kết với nhau.
Đây là nỗ lực của người mới của tôi trong việc sử dụng mysql
mô-đun Node.js với lồng nhau:
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);
});
});
}
Sau đây là viết lại bằng cách sử dụng các chức năng bên trong được đặt tên. Hàm ngoài with_connection
có thể được sử dụng như một bộ giữ cho các biến cục bộ. (Ở đây, tôi đã có các thông số sql
, bindings
, cb
mà hành động theo một cách tương tự, nhưng bạn chỉ có thể xác định một số biến địa phương bổ sung trong 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);
}
Tôi đã nghĩ rằng có lẽ có thể tạo ra một đối tượng với các biến thể hiện và sử dụng các biến thể hiện này để thay thế cho các biến cục bộ. Nhưng bây giờ tôi thấy rằng cách tiếp cận trên sử dụng các hàm lồng nhau và các biến cục bộ đơn giản và dễ hiểu hơn. Phải mất một thời gian để học OO, có vẻ như :-)
Vì vậy, đây là phiên bản trước của tôi với một biến đối tượng và thể hiện.
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); });
}
Nó chỉ ra rằng bind
có thể được sử dụng để một số lợi thế. Nó cho phép tôi loại bỏ các hàm ẩn danh hơi xấu xí mà tôi đã tạo mà không làm được gì nhiều, ngoại trừ tự chuyển tiếp đến một cuộc gọi phương thức. Tôi không thể truyền trực tiếp phương thức này vì nó có liên quan đến giá trị sai của this
. Nhưng với bind
, tôi có thể chỉ định giá trị this
mà tôi muốn.
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);
}
Tất nhiên, không có cái nào trong số này là JS phù hợp với mã hóa Node.js - tôi chỉ dành vài giờ cho nó. Nhưng có lẽ với một chút đánh bóng kỹ thuật này có thể giúp đỡ?