EVENT(事件)的作用
在node中很多异步方法需要监听事件,比如数据传输时需要监听流是否传输成功(data事件),数据是否传输完毕(end事件)。所以需要一个模块用来存储事件相关的操作(事件注册、事件监听、事件触发).
EVENT的机制
- 对于需要事件相关操作的函数,只需将其构造函数的原型指向事件的构造函数。这样其实例就能取得事件操作的方法。
- 对于事件库本身,提供事件的注册、监听、触发、取消绑定以及事件方法池。
EVENT实现原理
- 设定一个事件方法池。
- 当监听事件时,将事件名与其对应回调函数放入方法池。
- 触发事件时,从方法池中找到相应事件名,依次执行事件名下保存的回调函数。
代码实现
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061//事件构造函数function Event () {//事件方法池this._events={};}//事件的监听Event.prototype.on=function (eventName,callback) {var listeners=this._events[eventName];//如果事件方法池中存在对应方法名if (listeners) {//在对应方法名数组中新加入一个回调函数listeners.push(callback);} else {//事件方法池中对应方法名赋值为一个含回调函数的数组this._events[eventName]=[callback];}}//事件的触发Event.prototype.emit=function (eventName) {//第一项传参(也是形参)是事件名,从第二项开始就是传递给回调函数的参数,这里将这些参数保存在数组里var args=Array.prototype.slice.call(arguments,1);var listeners=this._events[eventName];//如果事件方法池中存在相应的方法名if (listeners) {for (var i=0;i<listeners.length;i++) {//依次执行方法名所对应的回调函数listeners[i].apply(null,args);}} else {console.log('对应方法不存在')}}//事件的移除Event.prototype.removeListener=function (eventName,callback) {this._events[eventName].filter(function (fn){return fn!=callback;})}//只执行一次的事件Event.prototype.once=function (eventName,callback) {//原理是执行完回调函数后移除这个事件//存储this指向,用以在one函数中调用指向once函数var that=this;function one () {//存储可能的传参var args=Array.prototype.slice.call(arguments);//执行回调函数callback.apply(that,args);//执行完后移除事件,这里的this指向的是事件实例this.removeListener(eventName,one);}//监听名为one的函数this.on(eventName,one);}module.exports=Event;
使用方法
|
|