不明白?不要紧。举个最简单例子,女人失恋了会哭,还会找新男友,在这里哭和找男友至关于订阅女人失恋的回调,何时执行呢?当发布女人失恋这件事的时候,说的这么抽象,直接来一段代码吧html
// 声明EventEmitter事件发生器构造函数
function EventEmitter() {
this._events = Object.create(null);
}
//on 订阅方法实现 由于在实例上调用,因此写在原型上
EventEmitter.prototype.on = function(type,callback){
// 若是实例不存在则建立一个空对象,Object.create(null)没有链
if(!this._events) {
this._events = Object.create(null);
}
if(this._events[type]){ //若是失恋有对应的值,直接往数组push
this._events[type].push(callback)
}else { //第一次订阅,没有失恋,就声明{失恋:[cry]}
this._events[type] = [callback];
}
};
// emit方法实现
EventEmitter.prototype.emit = function(type){
if(this._events[type]){ //{失恋:[cry,eat]} 若是失恋对应有值,依次执行里面的方法
this._events[type].forEach(fn=>fn())
}
};
module.exports = EventEmitter
复制代码
// 移除订阅事件的方法
EventEmitter.prototype.removeListener = function(type,callback){
if(this._events[type]){
// 返回false就表示不要了,用filter实现去重
this._events[type] = this._events[type].filter(fn=>fn!==callback)
}
};
复制代码
// removeAllListeners 移除全部的监听者
EventEmitter.prototype.removeAllListeners = function(){
//简单粗暴,直接赋值空对象 {}
this._events = Object.create(null);
};
复制代码
// once实现
EventEmitter.prototype.once = function(type,callback,flag){
// 先绑定 调用后再删除,运用了one函数 {失恋:one}
let one = (...args)=> {
callback(...args);
this.removeListener(type, one);
}
//自定义属性 由于实例中没有one属性
one.l = callback;
this.on(type,one)
};
// 移除订阅事件的方法
EventEmitter.prototype.removeListener = function(type,callback){
if(this._events[type]){
// 返回false就表示不要了,用filter实现去重
this._events[type] = this._events[type].filter(fn=>fn!==callback && fn.l!==callback)
}
};
复制代码
// - 错误例子 错误例子 错误例子(重要事情说三遍)
//你可能会这么写,但刚绑定就移除拉,体会这意思了吧
EventEmitter.prototype.once = function(type,callback){
//先绑定在移除
this.on(type,callback);
this.removeListener(type,callback)
};
复制代码
简单说就是能够监控到订阅的事件类型,上源码看下如何实现node
//on 订阅方法实现 由于在实例上调用,因此写在原型上
EventEmitter.prototype.on = function(type,callback){
// 若是实例不存在则建立一个空对象,Object.create(null)没有链
if(!this._events) {
this._events = Object.create(null);
}
if(type!=="newListener"){
if(this._events["newListener"]){
this._events["newListener"].forEach(fn=>fn(type))
}
}
if(this._events[type]){ //若是失恋有对应的值,直接往数组push
this._events[type].push(callback)
}else { //第一次订阅,没有失恋,就声明{失恋:[cry]}
this._events[type] = [callback];
}
};
复制代码