Nodejs模块中的作用域问题

我刚刚开始与节点,我被卡住pipe理“回拨地狱”。 我已经成功地设法使用Event发射器来从模块中激发主要js文件中的事件,但我无法弄清楚如何在模块中的callback中使用范围从事件触发事件。 此外,我在调用模块中的callback函数时遇到问题。

具体来说,这里:

rows.forEach(function(thisRow, index, array) { myDb.query("SELECT COUNT(a.studentID) as total, m.fName, m.lName, m.id " + "from `absences` a join `members` m on a.studentID = m.id " + "where a.aDate>=" + myDb.escape(thisRow['beginDate']) + " and " + "a.aDate<=" + myDb.escape(thisRow['endDate']) + " and a.aDate<'" + today + "' and m.memGroup = " + myDb.escape(thisRow['orchName']) + "GROUP BY a.studentID ORDER BY total DESC", function(error, row){ if(row.length > 0) { retValues.push({"fullName": thisRow.fullName, "shortName": thisRow.shortName, "absences": row}); } if (index === array.length - 1) { //This call to this fails because, I believe, it is out of scope. //How can I access this? OR how can I emit an event here that will //trigger the listener in the index.js? this._alertServer; console.log(retValues); console.log("Done"); } }); }); 

完整的代码可以在http://pastebin.com/Gw6kzugkfind

编辑 – 上面可能的答案正是你应该寻找的。 以下是我在我的情况下最终做的事情。 谢谢大家!

正如评论中所解释的那样,你不能在callback中使用this 。 您需要在callback之外捕获它,如下所示:

 rows.forEach(function(thisRow, index, array) { var self = this; // the critical line myDb.query("SELECT COUNT(a.studentID) as total, m.fName, m.lName, m.id " + "from `absences` a join `members` m on a.studentID = m.id " + "where a.aDate>=" + myDb.escape(thisRow['beginDate']) + " and " + "a.aDate<=" + myDb.escape(thisRow['endDate']) + " and a.aDate<'" + today + "' and m.memGroup = " + myDb.escape(thisRow['orchName']) + "GROUP BY a.studentID ORDER BY total DESC", function(error, row){ if(row.length > 0) { retValues.push({"fullName": thisRow.fullName, "shortName": thisRow.shortName, "absences": row}); } if (index === array.length - 1) { // Use self here, not this self._alertServer; console.log(retValues); console.log("Done"); } }); }); 

虽然可能不是最优雅的想要处理这种情况,但我最终所做的只是在短短的时间内将这些内容传递给了Android程序。

 _getAttendanceBySession = function(err, rows, retValue, context) { /* Gets attendance for each session given err -> Errors returned from last mySQL query rows -> JS Object of session list retValue -> string being passed to webserver context -> 'this' */ var tmpHTML; tmpHTML = retValue; myDb.getConnection(function(err, conn) { rows.forEach(function(thisRow, index, array) { conn.query("SELECT COUNT(a.studentID) as total, m.fName, m.lName, m.id from `absences` a join `members` m on a.studentID = m.id where a.aDate>=" + (myDb.escape(thisRow.beginDate)) + " and a.aDate<=" + (myDb.escape(thisRow.endDate)) + " and a.aDate<'" + today + "' and m.memGroup = " + (myDb.escape(thisRow.orchName)) + " GROUP BY a.studentID ORDER BY total DESC", function(error, row) { if (row.length > 0) { tmpHTML = tmpHTML + ("<h3 class='text-center'>" + thisRow.fullName + "</h3><div class='panel-group' id='" + thisRow.shortName + "'>"); row.forEach(function(studentRow, index2, array2) { var tmpLabel; if (studentRow.total === 1) { tmpLabel = 'label-default'; } else if (studentRow.total === 2) { tmpLabel = 'label-warning'; } else { tmpLabel = 'label-danger'; } tmpHTML = tmpHTML + ("<div class='panel panel-default'><div class='panel-heading'><a class='attendance-link panel-title' data-toggle='collapse' data-parent='#" + thisRow.shortName + "' href='#" + studentRow.id + "-details'><span class='label pull-left " + tmpLabel + "'>" + studentRow.total + "</span>" + studentRow.fName + " " + studentRow.lName + "</a></div><div class='panel-body collapse' id='" + studentRow.id + "-details'></div></div>"); if (index2 === array2.length - 1) { tmpHTML = tmpHTML + "</div>"; } }); } if (index === array.length - 1) { conn.release(); context.emit("send-page", tmpHTML); } }); }); }); };