ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

event

2020-03-22 19:54:31  阅读:224  来源: 互联网

标签:EmitterEx 监听 listener listeners 监听器 event


## 开场介绍 5分钟
* 确认上课的环境 * 自我介绍 * 课程内容 EventEmitter     EventEmitter是Node.js的内置模块events提供的一个类,它是Node事件流的核心,EventEmitter是服务端的东西,     前端已经有event-emitter的npm库     地址: https://www.npmjs.com/package/event-emitter           高级浏览器也有原生提供的EventTarget这种实现事件监听和触发的API     地址: https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget           但是它们和Node.js的事件API都有或多或少的区别,今天我们就来实现一个前端版本的EventEmitter     我本章demo的github地址如下     https://github.com/penghuwan/event-emitter
* 引导学员加微信

1. 咱们为什么要学这堂课? * 了解观察者模式和 发布订阅模式 的区别  * 不要一味的使用别人的插件, 自己可以动手造轮子吗, 自己能开发插件供别人学习吗?
2. 封装完这个 EventEmitter有什么作用? 如何运用到项目中去? * 可以简单演示下在项目中的使用?
## 观察者和发布订阅模式的区别

## 项目中常见的发布订阅模式 
* 父子组件传值 子组件 v-on:eventKK   -   父组件 this.$emit('eventKK') * 中央数据总线 ```javascript     var bus = new Vue()     // 触发组件 A 中的事件     bus.$emit('id-selected', 1)     // 在组件 B 创建的钩子中监听事件     bus.$on('id-selected', function (id) {     // ...     }) ``` * vuex状态管理
### 二、API介绍 我们要实现的API有:
* on(event, listener):为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。 * emit(event, [arg1], [arg2]): 按监听器的顺序执行执行每个监听器 * addListener(event, listener):on的同名函数(alias) * once(event, listener): 和on类似,但只触发一次,随后便解除事件监听 * removeListener(event, listener): 移除指定事件的某个监听回调 * removeAllListeners([event]):移除指定事件的所有监听回调 * setMaxListeners(n):用于提高监听器的默认限制的数量。(默认10监听回调个产生警告)
![avatar](./pic/event.png)

eventEmitter具体代码
1. 首先我们需要写一个EventEmitter构造函数,给它设置两个属性listeners和maxListener
```javascript // 采用发布订阅模式 class EventEmitter {     constructor(max){         this.listeners = {};           //用于存放事件监听器函数,结构为:         // {         //     "event1": [f1,f2,f3],         //     "event2": [f4,f5],         //     ...         //   }         this.maxListener = max || 10;          //设置的某个事件能够添加的监听器的最大数量,超过这个值,需要在控制台输出警告,但不会报错阻止
    }     //监听事件     // 1.判断该事件的监听器数量是否已超限,超限则报警告     // 2.判断该事件监听器数组是否初始化,若未初始化,则将listeners[event]初始化为数组,并加入监听器cb     // 3.若监听器数组已经被初始化,则判断数组中是否已存在cb,不存在则添加,已存在则不做操作。     on(event,cb){         var listener = this.listeners;         //step 1 判断该事件的监听器数量是否已超限,超限则报警告         if(listener[event] && listener[event].length>=this.maxListener) {             throw console.error('监听器的最大数量是%d,您已超出限制', this.maxListener)         }         //step 2 判断数组是否已初始化         // Array.isArray(listener[event])         // Object.prototype.toString.call(test) == '[object Array]'         if(listener[event] instanceof Array) {             //已经初始化,无需重复添加             if(!listener[event].includes(cb)){                 listener[event].push(cb);             }          } else {             listener[event] = [];             listener[event].push(cb);         }
    }     // 指定addListener等于on方法     addListener(){         this.on.apply(this,arguments);     } //  (1)通过Array.from(arguments)取出方法的参数列表args, // (2)调用args.shift踢掉数组第一个参数即event,留下来的这些是要传给监听器的 // (3)遍历监听器,通过apply方法把上面得到的args参数传进去     emit(event){         //判断有没有这个event         if(!this.listeners[event]){             return;         }         //因为可能会有参数          var args = Array.from(arguments);             args.shift();
         //循环遍历所有监听到event的事件 ,统一执行         // this.listeners[event].forEach((cb,index)=>{         //     cb.apply(null,args);         // })         // 简写为:         this.listeners[event].forEach(cb=>cb.apply(null,args))     }
    // 1.通过indexOf确定监听器回调在数组listeners[event]中的位置     // 2.通过splice(i,1)删除之     removeListener(event,listener){          //判断有没有这个event          var listeners = this.listeners[event];          if(listeners && listeners.length>0){             var i = listeners.indexOf(listener);             if (i >= 0) {                 listeners.splice(i, 1);             }          }     } // 添加事件监听,只能执行一次  // once方法是on方法和removeListener方法的结合:  // 用on方法监听,在回调结束的最后位置,通过removeListener删掉监听函数自身     once(){         var self = this;         function fn() {             var args = Array.prototype.slice.call(arguments);             listener.apply(null, args);             self.removeListener(event, fn);         }         this.on(event, fn)     }      // 清空listeners[event]数组     removeAllListener(){         this.listeners[event] = [];     }     setMaxListeners(num){         this.maxListener = num;     }
} ``` html部分
```javascript <body>     <div id="itapp">         <button type="button" id="btnTest">测试</button>     </div>     <script src="./main.js"></script>     <script>             var EmitterEx = new EventEmitter();         function fn1(data){             console.log(data)             console.log('监听laney');         }         function fn2(){             console.log('监听song');         }         EmitterEx.on('laney',fn1);         EmitterEx.on('song',fn2);
        EmitterEx.emit('laney',{             name:'laney',             age:'20'         })     </script> </body> ```

index.html测试使用 
<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>event emiter</title> </head> <body>     <div id="itapp">         <button type="button"  id="btnTest">测试</button>     </div>     <script src="./main.js"></script>     <script>                  var EmitterEx = new EventEmitter();
          // //测试 最多监听的 总数 setMaxListeners,这个需要在监听之前调用         EmitterEx.setMaxListeners(1);
        //测试 on emit         function fn1(data){             console.log(data)             console.log('监听laney');         }         function fn11(data){             console.log(data)             console.log('监听laney1');         }         function fn2(){             console.log('监听song');         }         EmitterEx.addListener('laney',fn1) //监听方式一         // EmitterEx.on('laney',fn1);  //监听方式二         EmitterEx.on('song',fn2);
        // EmitterEx.on('laney',fn11);         // EmitterEx.on('song',fn2);
        btnTest.onclick = function(){             EmitterEx.emit('laney',{                 name:'laney',                 age:'20'             })             EmitterEx.emit('song',{                 name:'song',                 age:'1'             })         }         
           // //测试 removeListener         //    EmitterEx.removeListener('laney',fn1)
        // //测试  removeAllListener         // EmitterEx.removeAllListener();
            </script> </body> </html>

标签:EmitterEx,监听,listener,listeners,监听器,event
来源: https://www.cnblogs.com/laneyfu/p/12547877.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有