Node.js NodeJS:无法发射事件“对象…”{}没有方法“发射”

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

我学习了一些Nodejs教程,并完成了一个简单的REST Web服务。该Web服务侦听/api/以获取电子邮件和密码,然后在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);
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;