这篇文章主要介绍怎样模拟实现节点中的事件模块,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
Nodejs的大部分核心API都是基于异步事件驱动设计的,事件驱动核心是通过节点中事件对象来实现事件的发送和监听回调绑定,我们常用的流模块也是依赖于事件模块是来实现数据流之间的回调通知,如在数据到来时触发数据事件,流对象为可读状态触发可读的事件,当数据读写完毕后发送结束事件。
既然事件模块如此重要,我们有必要来学习一下事件模块的基本使用,以及如何模拟实现事件模块中常用的API
<强>一、事件模块的基本使用以及简单实现强>
首先我们了解一下事件模块的基本用法,其实事件模块本质上是观察者模式的实现,所谓观察者模式就是:
它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知
观察者模式有对应的观察者以及被观察的对象,在事件模块中,对应的实现就是> const EventEmitter =,要求(& # 39;事件# 39;); class MyEmitter  extends EventEmitter  {} const myEmitter =, new MyEmitter (); myEmitter.on(& # 39;嗨& # 39;,,(str),=祝辞,{ ,console.log (str); }); myEmitter.emit(& # 39;嗨& # 39;,& # 39;你好& # 39;);
从上述的使用中,我们可以知道> class EventEmitter { ,构造函数(){ #才能事件监听函数保存的地方 this.events才能={}; ,} ,在(eventName侦听器){ if 才能;(this.events [eventName]), { ,,this.events [eventName] .push(听众); ,,},{else ,,#如果没有保存过,将回调函数保存为数组 ,,this.events [eventName],=,(听众); ,,} ,} ,发出(eventName) { #才能发出触发事件,把回调函数拉出来执行 this.events才能(eventName),,,, this.events [eventName] .forEach (listener =祝辞,侦听器()) ,} }
上述就实现了一个简单的EventEmitter类、下面来实例一下:
let event =, new EventEmitter (); event.on(& # 39;嗨& # 39;,函数(){ ,console.log(& # 39;你好& # 39;); }); event.emit(& # 39;嗨& # 39;); #输出:你好
完善:我们注意到在原生的EventEmitter类中,排放是可以传递参数到我们的回调函数中,那么我们实现的类也应该支持传递参数。我们对排放进行如下更改
发出(eventName…rest) { ,#发出触发事件,把回调函数拉出来执行 ,this.events (eventName),,,, this.events [eventName] .forEach (listener =祝辞,listener.apply (rest),) }
完善之后,重新实例化,如下:
let event =, new EventEmitter (); event.on(& # 39;嗨& # 39;,函数(str) { ,console.log (str); }); event.emit(& # 39;嗨& # 39;,& # 39;你好& # 39;); #输出:你好
<强>二、事件模块中常用的api 强>
事件模块中除了> EventEmitter.prototype.addListener=EventEmitter.prototype.on
<强> 2。removeListener与从方法使用与实现强>
removeListener方法可以从指定名字的监听器数组中移除指定的侦听器,这样的话,当再次发出事件的时候,不会触发> const EventEmitter =,要求(& # 39;事件# 39;); class MyEmitter  extends EventEmitter  {} const myEmitter =, new MyEmitter (); let callback =, (str),=祝辞,{ ,console.log (str); } myEmitter.on(& # 39;嗨& # 39;,,回调); myEmitter.emit(& # 39;嗨& # 39;,& # 39;你好& # 39;);#输出:你的好 myEmitter.removeListener(& # 39;嗨& # 39;,回调); myEmitter.emit(& # 39;嗨& # 39;,& # 39;你好& # 39;);#无输出
实现思路:我们只要在执行removeListener函数的时候,将先前保存的回调函数去除掉即可
removeListener (eventName侦听器),{ ,#保证回调函数数组存在,同时去除指定的侦听器 ,this.events (eventName),,,, this.events [eventName],=, this.events [eventName] .filter (l =祝辞,l !=,侦听器); }
同时removeListener与从方法也是功能完全相同,只是命名不同,因此可以通过如下方法赋值:
EventEmitter.prototype.removeListener=EventEmitter.prototype.off
<强> 3。removeAllListeners方法使用与实现
强>