NodeJS:不能发射事件“Object … {}没有方法”emit“

我遵循了几个通过简单的REST web服务获得的Nodejs教程。 这个web服务监听/ api /帐户的电子邮件和密码,然后继续在Cassandra集群中查找。 我使用EventEmitter来避免callback地狱。 一切正常,直到试图发射('成功'):

events.js:72 throw er; // Unhandled 'error' event ^ TypeError: Object SELECT * FROM accounts WHERE email_accounts=?,test@gmail.com,77ddcc8d868e1532f86f0e25f35d43e5,function _checkPassword(error, response) { var rows=response.rows; if (_checkForErrors(error, rows , 'password')) { return false; } else { if ( rows.length == 1 ) { console.log('got user profile with password_accounts ' + rows[0].pwd_accounts); this.emit('success', rows[0] ); } } } has no method 'emit' at Array._checkPassword (/home/scoulibaly/node/login.js:33:10) at /home/scoulibaly/node/node_modules/node-cassandra-cql/index.js:220:16 at Connection.handleResult (/home/scoulibaly/node/node_modules/node-cassandra-cql/lib/connection.js:308:3) at ResultEmitter.EventEmitter.emit (events.js:106:17) at ResultEmitter.bufferAndEmit (/home/scoulibaly/node/node_modules/node-cassandra-cql/lib/streams.js:456:10) at ResultEmitter.each (/home/scoulibaly/node/node_modules/node-cassandra-cql/lib/streams.js:440:17) at ResultEmitter._write (/home/scoulibaly/node/node_modules/node-cassandra-cql/lib/streams.js:413:10) at doWrite (_stream_writable.js:223:10) at writeOrBuffer (_stream_writable.js:213:5) at ResultEmitter.Writable.write (_stream_writable.js:180:11) 

我的主要是一个server.js。 我使用Express和router()来设置路由:

 // server.js // BASE SETUP // ============================================================================= // call the packages we need var express = require('express'); // call express var app = express(); // define our app using express var bodyParser = require('body-parser'); var Login = require('./login'); // configure app to use bodyParser() // this will let us get the data from a POST app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); var port = process.env.PORT || 8080; // set our port // ROUTES FOR OUR API // ============================================================================= var router = express.Router(); // get an instance of the express Router // middleware to use for all requests router.use(function(req, res, next) { // do logging console.log('Something is happening.'); next(); // make sure we go to the next routes and don't stop here }); router.route('/accounts') // get the account with that id (accessed at GET http://localhost:8080/api/accounts/:account_id) .get(function(req, res) { var login = new Login(req.query.email, req.query.password); login.on('error', function (error) { res.writeHead(500); res.end(); }); login.on('failure', function (reason) { if (reason == 'email') { res.end('Wrong email!'); } else if (reason == 'password') { res.end('Wrong password!'); } }); login.on('success', function (data) { res.json(data); }); login.perform(); }); // test route to make sure everything is working (accessed at GET http://localhost:8080/api) router.get('/', function(req, res) { res.json({ message: 'hooray! welcome to our api!' }); }); // more routes for our API will happen here // REGISTER OUR ROUTES ------------------------------- // all of our routes will be prefixed with /api app.use('/api', router); // START THE SERVER // ============================================================================= app.listen(port); console.log('Magic happens on port ' + port); 

我的login.js扩展了EventEmitter:

 // login.js var util = require('util'); var eventEmitter = require('events').EventEmitter; var cql = require('node-cassandra-cql'); function Login(email,password) { // Error checking function _checkForErrors(error, rows, reason) { if (error) { console.log('emit err'); this.emit('error', error); return true; } if (rows.length < 1) { console.log('emit fail'); this.emit('failure', reason); return true; } return false; } // Check {email,pwd} function _checkPassword(error, response) { var rows=response.rows; if (_checkForErrors(error, rows , 'password')) { return false; } else { if ( rows.length == 1 ) { console.log('got user profile with password_accounts ' + rows[0].pwd_accounts); this.emit('success', rows[0] ); } } } function perform() { var client = new cql.Client({hosts: ['localhost', 'localhost'], keyspace: 'node'}); client.execute('SELECT * FROM accounts WHERE email_accounts=?', [ email , password ], _checkPassword ); } this.perform = perform; } util.inherits(Login, eventEmitter); module.exports = Login; 

它看起来像this.emit()行中的“this”引用了CQL对象。 根据我的理解,只要数据准备就绪,cql驱动程序就会调用callback函数,所以“this”对象不再是一个Login对象。 我错了吗 ? 如何使emit()正常工作?

谢谢

在您的login对象定义的顶部附近,通过以下方式创build一个句柄:

 var _this = this; 

然后在调用emit方法时使用_this来代替this_checkPassword据说closures _this (它不能这样做)。

this关键字是一个特殊的雪花,在调用封闭函数时被dynamic地绑定; 如果你把一个引用this函数传给其他函数,确保this是你的想法。 🙂