我不确定标题,但我想不出更好的标题。我的问题是,我试图连续避免过多的回调,所以我使用了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.');
我认为,在第二个请求期间,节点使用与之前相同的侦听器,因此导致错误的响应对象相同。
我的问题是:我该如何避免这种情况?
提前谢谢你们!
答案 0 :(得分:1)
是的,当您第二次拨打电话时,您正在添加"已验证"并且" notValidated"事件再次(并在第三次你将再次添加等等...)。您可以使用事件发射器的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
要删除事件侦听器,您可以使用removeListener方法
抱歉,您的示例代码非常糟糕。事件发射器是很酷的模式,但不是这个东西。不要害怕回电,他们不是那么可怕。