Node.js NodeJS:无法发射事件“对象…”{}没有方法“发射”
我学习了一些Nodejs教程,并完成了一个简单的REST Web服务。该Web服务侦听/api/以获取电子邮件和密码,然后在Cassandra集群中进行查找。 我使用EventEmitter来避免回调地狱。在尝试发射“成功”之前,一切正常:Node.js NodeJS:无法发射事件“对象…”{}没有方法“发射”,node.js,express,cql,Node.js,Express,Cql,我学习了一些Nodejs教程,并完成了一个简单的REST Web服务。该Web服务侦听/api/以获取电子邮件和密码,然后在Cassandra集群中进行查找。 我使用EventEmitter来避免回调地狱。在尝试发射“成功”之前,一切正常: events.js:72 throw er; // Unhandled 'error' event ^ TypeError: Object SELECT * FROM accounts WHERE email_ac
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);
My 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驱动程序在数据准备就绪时调用回调,因此“this”对象不再是登录对象。我错了吗?如何使emit正常工作
谢谢在登录对象定义的顶部附近,通过以下方式创建一个句柄: 然后在调用emit方法时使用_this而不是this。_checkPassword被称为关闭_this,但它不能关闭它
this关键字是一个特殊的雪花,在调用封闭函数时会动态绑定;如果您将引用此关键字的函数传递给其他函数,请确保这是您所认为的。omg,我以为这是我用var self=this尝试过的;我做了您建议的更改。确实工作得很好!非常感谢。
var _this = this;