2015-01-12 43 views
0

我不确定标题,但我想不出一个更好的标题。我的问题是,我试图避免连续回调太多,所以我使用了EventEmitter。 我有一个模块内的功能,来检查,如果AA给出的用户名和密码匹配的数据库条目:使用后销毁EventEmitter侦听器

var PasswordChecker = function() { 
events.EventEmitter.call(this); 
var _self = this; 

this.checkPassword = function (username,password) { 
    _self.emit("findOne",username,password); 
}; 

var _findOne = function (username,password) { 
    UserSchema.findOne({'username': username}, function (err, result) { 
     if (!err && result.username === username) { 
      _self.emit("passwordCheck", password, result.password); 
     } else { 
      _self.emit("notValidated"); 
     } 
    }); 
}; 

var _passwordCheck = function (password, res_password) { 
    bcrypt.compare(password,res_password, function (err, res) { 
     if (err){ 
      _self.emit("notValidated"); 
     } else { 
      _self.emit("validated") 
     } 
    }); 
}; 

_self.on("findOne", _findOne); 
_self.on("passwordCheck",_passwordCheck); 
}; 

util.inherits(PasswordChecker,events.EventEmitter); 
module.exports.PasswordChecker = new PasswordChecker; 

我呼吁在我的路线之一此功能:第一次

router.post('/checkPassword', function(req, res){ 

user.PasswordChecker.on("validated", function() { 
    console.log("Validated"); 
    res.status(200).send({success:true}); 
}); 
user.PasswordChecker.on("notValidated", function() { 
    console.log("notValidated"); 
    res.status(400).send({success:false}); 

}) 
user.PasswordChecker.checkPassword(req.body.username, req.body.password); 
}); 

我做的请求后,一切正常,但是当我尝试第二次,我得到的错误:

http.js:690 
throw new Error('Can\'t set headers after they are sent.'); 

我认为,第二个请求时,节点全光照g与之前相同的监听器,因此也是导致错误的相同响应对象。

我的问题是:我该如何避免这种情况?

谢谢各位提前!

回答

1

是的,当您第二次打电话发帖时,您将再次添加“已验证”和“未验证”事件的听众(并在第三次您将再次添加等等..)。您可以使用事件发射的once方法来避免这个问题:

user.PasswordChecker.once("validated", function() { 
    console.log("Validated"); 
    res.status(200).send({success:true}); 
}); 
user.PasswordChecker.once("notValidated", function() { 
    console.log("notValidated"); 
    res.status(400).send({success: false}); 

}); 

PS

  1. 要删除事件侦听器可以使用removeListener方法

  2. 抱歉,代码的例子真的很糟糕。事件发射器是酷炫的模式,但不是这个东西。不要害怕回调,他们不会太可怕。

+0

非常感谢您的帮助。我从教程中得到了这样做的想法。你为什么会说使用EventEmitter在这里没有用? – Simon

相关问题