หลังจากที่คนอื่นตอบคุณระบุว่าปัญหาของคุณคือตัวแปรท้องถิ่น ดูเหมือนว่าวิธีง่าย ๆ ในการทำเช่นนี้คือการเขียนฟังก์ชันภายนอกหนึ่งตัวเพื่อเก็บตัวแปรท้องถิ่นเหล่านั้นจากนั้นใช้กลุ่มฟังก์ชันภายในที่มีชื่อและเข้าถึงพวกเขาตามชื่อ ด้วยวิธีนี้คุณจะสามารถซ้อนสองส่วนลึก ๆ ได้โดยไม่คำนึงถึงฟังก์ชันที่คุณต้องการรวมเข้าด้วยกัน
นี่คือความพยายามของมือใหม่ในการใช้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);
}
ฉันคิดว่าบางทีมันอาจเป็นไปได้ที่จะสร้างวัตถุที่มีตัวแปรอินสแตนซ์และใช้ตัวแปรอินสแตนซ์เหล่านี้เพื่อทดแทนตัวแปรท้องถิ่น แต่ตอนนี้ฉันพบว่าวิธีการข้างต้นโดยใช้ฟังก์ชั่นที่ซ้อนกันและตัวแปรท้องถิ่นนั้นง่ายและเข้าใจง่ายขึ้น ใช้เวลาสักครู่เพื่อคลายความเข้าใจ 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 - ฉันใช้เวลาสองสามชั่วโมงกับมัน แต่อาจใช้เทคนิคนี้ช่วยหน่อยได้ไหม?