本文共 3325 字,大约阅读时间需要 11 分钟。
不明白?没关系。举个最简单例子,女人失恋了会哭,还会找新男朋友,在这里哭和找男朋友相当于订阅女人失恋的回调,什么时候执行呢?当发布女人失恋这件事的时候,说的这么抽象,直接来一段代码吧
// 声明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)};复制代码
简单说就是可以监控到订阅的事件类型,上源码看下如何实现
//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]; }};复制代码