深度解析node的EventEmitter

在使用EventEmitter的时候我们常用的方法主要有on、emit、once、off, 下面我们简单实现一下这些方法

  1. 在实现这些方法之前,我们必须有一个构造函数,并且需要导出去
function EventEmitter(){
    //这里使用Object.create创建对象,有人会问为什么不直接 this._events = {};
    //如果this._events = {} 这种方式上面是会存在__proto__  而Object.create创建的是没有的,是一个比较干净的对象
    this._events = Object.create(null);    
}

   //导出
module.exports = EventEmitter;
  1. on方法的实现
EventEmitter.prototype.on = function(eventName,callback){

    if(!this._events){   // 这里做判断的原因是解决如果一个新的对象继承了EventEmitter 但是没有this._events 属性
        this._events = Object.create(null)
    }

    if(eventName !== 'newListener'){
        if(this._events['newListener']){
            this._events['newListener'].forEach(fn=>fn(eventName))
        }
    }

    let arr = this._events[eventName] || (this._events[eventName] = []);
    arr.push(callback);
}
  1. emit方法的实现
EventEmitter.prototype.emit = function(eventName,...args){

    if(!this._events){
        this._events = Object.create(null)
    }

    if(this._events[eventName]){
        this._events[eventName].forEach(fn => {
            fn(...args);
        });
    }
}
  1. once方法的实现
EventEmitter.prototype.once = function(eventName,callback){
    const once = (...args)=>{
        callback(...args);
        this.off(eventName,once)
    }
    once.l = callback;
    this.on(eventName,once)
}
  1. off方法的实现
EventEmitter.prototype.off = function(eventName,fn){
    if(this._events[eventName]){
        this._events[eventName] = this._events[eventName].filter(item=>{
            //filter返回false就会被删掉
            return item !== fn && item.l !== fn;
        })
    }
}

你可能感兴趣的:(深度解析node的EventEmitter)