使用后销毁 EventEmitter Listener
Destroy EventEmitter Listener after use
我不确定标题,但我想不出更好的标题。我的问题是,我试图避免连续太多回调,所以我使用了 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);
});
我第一次制作 post-request 时,一切正常,但是当我第二次尝试时,出现错误:
http.js:690
throw new Error('Can\'t set headers after they are sent.');
我认为,在第二次请求期间,节点使用与以前相同的侦听器,因此使用相同的响应 object 导致错误。
我的问题是:如何避免这种情况?
先谢谢大家了!
是的,当您第二次调用 post 时,您将再次为 "validated" 和 "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 方法
抱歉,您的示例代码真的很糟糕。事件发射器是很酷的模式,但不适用于这些东西。不要害怕回调,回调没那么可怕
我不确定标题,但我想不出更好的标题。我的问题是,我试图避免连续太多回调,所以我使用了 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);
});
我第一次制作 post-request 时,一切正常,但是当我第二次尝试时,出现错误:
http.js:690
throw new Error('Can\'t set headers after they are sent.');
我认为,在第二次请求期间,节点使用与以前相同的侦听器,因此使用相同的响应 object 导致错误。
我的问题是:如何避免这种情况?
先谢谢大家了!
是的,当您第二次调用 post 时,您将再次为 "validated" 和 "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 方法
抱歉,您的示例代码真的很糟糕。事件发射器是很酷的模式,但不适用于这些东西。不要害怕回调,回调没那么可怕