详解如何模拟实现node中的Events模块(通俗易懂版)

2020-06-17 05:47:48易采站长站整理


emit(eventName,...rest){
#emit触发事件,把回调函数拉出来执行
this.events[eventName] && this.events[eventName].forEach(listener => listener.apply(this,rest))
}

完善之后,重新实例化,如下:


let event = new EventEmitter();
event.on('嗨',function(str){
console.log(str);
});
event.emit('嗨','你好');
#输出:你好

二、Events 模块中常用的 api

Events 模块中除了 on、emit 函数之外,还包含了很多常用的 api,我们一一来介绍几个实用的 api

API名称API方法描述
addListener(eventName, listener)on(eventName, listener)别名,为指定事件添加一个监听器到监听器数组的尾部
removeListener(eventName, listener)从名为 eventName 的事件的监听器数组中移除指定的 listener
removeAllListeners(eventName, listener)移除全部监听器或指定的 eventName 事件的监听器
once(eventName, listener)添加单次监听器 listener 到名为 eventName 的事件
listeners(eventName)返回名为 eventName 的事件的监听器数组的副本
setMaxListeners(n)可以为指定的 EventEmitter 实例修改监听器数量限制

1. addListener 与 on 方法使用与实现

在 Events 模块中,addListener 与 on 方法的使用是完成相同的,只是名字不同,我们可以通过原型来给两个函数建立相等关联


EventEmitter.prototype.addListener=EventEmitter.prototype.on

2. removeListener 与 off 方法使用与实现

removeListener 方法可以从指定名字的监听器数组中移除指定的 listener,这样的话,当再次 emit 事件的时候,不会触发 on 绑定的回调函数,如下:


const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let callback = (str) => {
console.log(str);
}
myEmitter.on('嗨', callback);
myEmitter.emit('嗨','你好');#输出:你好
myEmitter.removeListener('嗨',callback);
myEmitter.emit('嗨','你好');#无输出

实现思路:我们只要在执行 removeListener 函数的时候,将先前保存的回调函数去除掉即可


removeListener (eventName,listener) {
#保证回调函数数组存在,同时去除指定的listener
this.events[eventName] && this.events[eventName] = this.events[eventName].filter(l => l != listener);
}

同时 removeListener 与 off 方法也是功能完全相同,只是命名不同,因此可以通过如下方法赋值: