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

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

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

EventEmitter.prototype.removeListener=EventEmitter.prototype.off

3. removeAllListeners 方法使用与实现

removeAllListeners 移除全部监听器或指定的 eventName 事件的监听器,其实 removeAllListeners 就包含了 removeListener 的功能,只是 removeListener 只能指定特定的监听器,removeAllListeners 可以移除全部监听器。

实现思路:在执行 removeAllListeners,将所有的回调函数都给去除即可

removeAllListeners (eventName) { #移除全部监听器 delete this.events[eventName] }

4. once 方法使用与实现

once 方法的描述是添加单次监听器 listener 到名为 eventName 的事件,其实就是通过 once 添加的监听器,只能执行一次,执行一次之后就会被销毁,不能再次执行

const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.once('嗨', (str) => { console.log(str); }); myEmitter.emit('嗨','你好'); myEmitter.emit('嗨','你好'); myEmitter.emit('嗨','你好'); #只能输出一次你好

实现思路:当 once 监听的事件回调函数执行之后,通过 removeListener 将事件监听器给解绑掉,那么事件再次被 emit 的时候,就不会再次执行回调,这样就能保证事件回调只能执行一次

once (eventName, listener) { #重新改变监听回调函数,使其执行之后可以被销毁 let reListener = (...rest) => { listener.apply(this,rest); #执行完之后解除事件绑定 this.removeListener(type,wrapper); } this.on(eventName,reListener); }

5. listeners 方法使用与实现

listeners 方法返回名为 eventName 的事件的监听器数组的副本,其实就是获取 eventName 中所有的回调函数,这个实现起来很容易,就不多赘述了,代码如下:

listeners (eventName) { return this.events[eventName] }

6. setMaxListeners 方法使用与实现

默认情况下,如果为特定事件添加了超过 10 个监听器,则 EventEmitter 会打印一个警告。 这有助于发现内存泄露, 但是,并不是所有的事件都要限制 10 个监听器。 emitter.setMaxListeners() 方法可以为指定的 EventEmitter 实例修改限制。 值设为 Infinity(或 0)表示不限制监听器的数量。

const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); let callback = (str) => { console.log(str); } for (let i = 0; i <= 11; i++) { myEmitter.on('嗨', callback); } myEmitter.emit('嗨', '你好');

输入结果如图:

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

实现思路:

我们先将特定事件的监听器最大设置为常量10

constructor(){ #事件监听函数保存的地方 this.events={}; #最大监听器数量 this._maxListeners = 10; }

然后在我们的 on 函数中,对这个监听器的数量进行判断,从而作出提示

on(eventName,listener){ if (this.events[eventName]) { this.events[eventName].push(listener); #如果超过最大限度,以及不为0,则作出内存泄漏提示 if (this._maxListeners != 0 && this.events[type].length >= this._maxListeners) { console.error('超过最大的监听数量可能会导致内存泄漏'); } } else { #如果没有保存过,将回调函数保存为数组 this.events[eventName] = [listener]; } }

我们也支持对 _maxListeners 变量根据用户的输入进行更改,即我们的 setMaxListeners() 函数

setMaxListeners(MaxListeners) { this._maxListeners = MaxListeners }

三、总结

本文从 node 的 Events 模块出发,然后去介绍了 Events 模块常用 API 的使用,从中通过一步一步简易去思考这些 API 使用的内部原理,简易的实现了这些 API,希望大家看完文章之后,能对 Events 模块有进一步的理解。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/2f837dba801c51cfe7e21d7be6f90fed.html