我遵循了一些Nodejs教程,通过一个简单的REST Web服务。此webservices侦听/ api / accounts以查找电子邮件和密码,然后继续在Cassandra集群中进行查找。 我使用EventEmitter来避免回调地狱。一切正常,直到尝试发射('成功'):
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;
看起来像这个&#39;在this.emit()行中引用CQL对象。根据我的理解,只要数据准备就绪,cql驱动程序就会调用回调,因此&#39;这个&#39; object不再是Login对象。我错了吗 ?如何使emit()正常工作?
谢谢
答案 0 :(得分:2)
在Login对象定义的顶部附近,通过以下方式创建this
的句柄:
var _this = this;
在调用_this
方法时,请使用this
代替emit
。据说_checkPassword
关闭超过_this
(它不能超过this
)。
this
关键字是一个特殊的雪花,在调用封闭函数时会动态绑定;如果您将引用this
的函数传递给其他函数,请确保this
符合您的想法。 :)