Node.js事件模块
常见用法
首先引入events模块,然后创建一个类继承这个模块。
这里采用了发布订阅模式
通过使用on方法,来注册一个事件,可以给一个事件添加多个动作。
通过使用emit方法,来触发一个事件,触发事件后,将注册事件中的所有动作依次执行。
const EventEmitter = require('events');
class Girl extends EventEmitter {
// ...
}
let girl = new Girl();
girl.on('我失恋了', function(){
console.log('哭');
});
girl.on('我失恋了', function(){
console.log('吃');
});
function shopping(){
console.log('购物');
}
function running(){
console.log('跑步');
}
girl.on('我失恋了', running);
girl.off('我失恋了', running); // 将添加的动作删除
girl.once('我失恋了', shopping); // 给这个事件添加一个动作,只执行一次,执行过之后,删除
girl.emit('我失恋了');
girl.emit('我失恋了');
主要的方法就这几个:on(‘newListener’)、off、once、emit
events模块中还有两个事件,newListener和removeListener
-
newListener:该事件在添加新监听器时被触发。
参数:
event - 字符串,事件名称
listener - 处理事件函数 -
removeListener:从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。
参数:
event - 字符串,事件名称
listener - 处理事件函数
event模块的原理
其实就是发布订阅模式
function EventEmitter() {
this._events = {};
}
EventEmitter.prototype.on = function (eventName, callback) {
if (!this._events) {
this._events = {};
}
if (eventName !== 'newListener') {
this.emit('newListener', eventName);
}
let events = (this._events[eventName] || []);
events.push(callback);
this._events[eventName] = events;
}
EventEmitter.prototype.emit = function (eventName, ...args) {
if (!this._events) {
this._events = {};
}
let callbacks = this._events[eventName];
callbacks && callbacks.forEach(cb => cb.call(this, ...args));
}
EventEmitter.prototype.once = function(eventName, callback) {
function one(...args) {
callback(...args);
this.off(eventName, one);
}
one.l = callback; // 增加标识
this.on(eventName, one); // 绑定one函数,最后one函数被触发后,再把one函数移除掉
}
EventEmitter.prototype.off = function (eventName, callback) {
if(!this._events) {
this._events = {};
}
this._events[eventName] = this._events[eventName].filter(fn =>{
return fn !== callback && fn.l !== callback;
})
}
module.exports = EventEmitter;