Nodejs学习item 2 -- events事件处理EventEmitter_js emit_event,自学Flutter

33 阅读7分钟

Vue

  • 什么是MVVM?

  • mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?

  • 组件之间的传值?

  • Vue 双向绑定原理

  • 描述下 vue 从初始化页面–修改数据–刷新页面 UI 的过程?

  • 虚拟 DOM 实现原理

  • Vue 中 key 值的作用?

  • Vue 的生命周期

  • Vue 组件间通信有哪些方式?

  • vue 中怎么重置 data?

  • 组件中写 name 选项有什么作用?

  • Vue 的 nextTick 的原理是什么?

  • Vuex 有哪几种属性?

    开源分享:docs.qq.com/doc/DSmRnRG… ee.on('some_events', function(foo, bar) {
    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); });

var isSuccess = ee.emit('some_events', 'Wilson', 'Zhong');//有返回值 ee.on('some_events', function(foo, bar) {
console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar ); }); ee.emit('some_events', 'zhong', 'wei');//不带返回值 var isSuccess2 = ee.emit('other_events', 'Wilson', 'Zhong'); console.log(isSuccess); console.log(isSuccess2);


示例进行了三次触发事件操作,其中`some_events`注册了监听,调用时`emit`函数会返回一个true,而`other_events`并没有注册监听,emit函数会返回一个false,表示该事件没有监听;当然也可以不用管这个返回值!


* **emitter.once(event, listener)**



/* EventEmitter.once(event, listener) 为事件注册一次性监听,触发一次后移除监听 参数1:event 字符串,事件名 参数2:回调函数 */ var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter();

ee.once('some_events', function(foo, bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); }); console.log('第一轮'); ee.emit('some_events', 'Wilson', 'Zhong'); console.log('第二轮'); var isSuccess = ee.emit('some_events', 'Wilson', 'Zhong'); console.log(isSuccess);


从上面示例代码执行结果可以看出,用emitter.once给`some_events`注册一个监听后,分两轮调用emitter.emit触发,第二轮会返回false;这表示用emitter.once注册监听和用前面讲的emitter.on注册监听略有不同,


emitter.once注册监听是一次性监听,当触发一次后,会移除该监听!当然,从名字上就看就比较明显了^\_^!


* **emitter.removeListener(event, listener)**

 先来看一个失败的场景~~~注意这里的listener是回调函数名字。



var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter(); ee.on('some_events', function(foo, bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); }); /* 看到API中removeListener移除方法时,以为应该是这样 但是结果^_^!!!!! */ ee.removeListener('some_events', function(){ console.log('成功移除事件some_events监听!');
}); console.log('第一轮'); ee.emit('some_events', 'Wilson', 'Zhong');


当我用emitter.on给some\_events注册了一个监听后,我用`emitter.removeListener`移除some\_events的监听,随后再调用emitter.emit去触发,最后发现不是按我想像的在进行!为什么呢?


我理所当然的认为emiiter.removeListener第二个参数是个回调函数,API还是要认真看清楚啊!!!


下面再看个成功的场景~~~



var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter(); var listener = function(foo,bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); } var listener2= function(foo,bar) { console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar ); } var listener3= function(foo,bar) { console.log("第3个监听事件,参数foo=" + foo + ",bar="+bar ); } ee.on('some_events', listener); ee.on('some_events', listener2); ee.on('some_events', listener3); /* EventEmitter.removeListener(event, listener) 移除指定事件的监听器 注意:该监听器必须是注册过的 PS:上一个例子之后以会失败,很大原因就是忽略了监听器,理所当然的认为传个事件名就OK了,所以就悲剧了! */ ee.removeListener('some_events', listener); ee.removeListener('some_events', listener3); ee.emit('some_events', 'Wilson', 'Zhong');


我用示例中写法,给some\_events添加了三个监听,又移除了第一个和第三个监听,最后再用emitter.emit触发some\_events,输出结果不难发现,用emitter.removeListener移除的第一个和第三个监听都没有再起作用,


想当然是害人地,原来emitter.removeListener的第二个参数是要移除的监听,而非移除成功后的回调函数……^\_^!


* **emitter.removeAllListeners([event])**


emitter.removeListener用过了,但一个事件可以有多个监听,需要全部移除时,一个个移除明显不是愉快的做法,不符合偷懒的天性!


让我们来体验一下emitter.removeAllListeners带来的便捷! 



/* EventEmitter.removeAllListeners([event]) 移除(批定事件)所有监听器 参数1:可选参数,event 字符串,事件名 */ var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter(); var listener = function(foo,bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); } var listener2= function(foo,bar) { console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar ); } ee.on('some_events', listener); ee.on('some_events', listener2); ee.on('other_events',function(foo,bar) { console.log("其它监听事件,参数foo=" + foo + ",bar="+bar ); });

ee.removeAllListeners('some_events'); ee.emit('some_events', 'Wilson', 'Zhong'); ee.emit('other_events', 'Wilson', 'Zhong');


看看上面的执行结果,你会发现给`some_events`注册了两个监听;给`other_events`注册了一个监听;我调用emitter.removeAllListeners传了some\_events事件名;


最后使用emitter.on函数触发some\_events和other\_events两个事件,最后发现`some_events`注册的两个监听都不存在,而other\_events注册的监听还存在;


这表示当 emitter.removeAllListeners传用事件名作为参数时,为移除传入事件名的所有监听,而不会影响其它事件监听!


emitter.removeAllListeners可以不传用事件名参数;直接执行



/* EventEmitter.removeAllListeners([event]) 移除(批量事件)所有监听器 参数1:可选参数,event 字符串,事件名 */ var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter(); var listener = function(foo,bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); } var listener2= function(foo,bar) { console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar ); } ee.on('some_events', listener); ee.on('some_events', listener2); ee.on('other_events',function(foo,bar) { console.log("其它监听事件,参数foo=" + foo + ",bar="+bar ); });

ee.removeAllListeners(); ee.emit('some_events', 'Wilson', 'Zhong'); ee.emit('other_events', 'Wilson', 'Zhong');


示例代码和传入参数时几乎一样,只是在调用emitter.removeAllListeners并没有传入指定事件名;


运行结果会发现some\_events和other\_events所有监听都不存在了,它会移除所有监听!(比较暴力的方法一般要慎用~~)


* **emitter.listeners(event)**



/* EventEmitter.listeners(event) //返回指定事件的监听数组 参数1:event 字符串,事件名
*/ var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter(); var listener = function(foo,bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); } var listener2= function(foo,bar) { console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar ); } ee.on('some_events', listener); ee.on('some_events', listener2); ee.on('other_events',function(foo,bar) { console.log("其它监听事件,参数foo=" + foo + ",bar="+bar ); });

var listenerEventsArr = ee.listeners('some_events'); console.log(listenerEventsArr.length) for (var i = listenerEventsArr.length - 1; i >= 0; i--) { console.log(listenerEventsArr[i]); };


给some\_events注册两个监听,调用emitter.listeners函数,传入`some_events`事件名,接收函数返回值;


从结果可以看出,返回值接收到`some_events`所有注册监听的集合!


* **emitter.setMaxListeners(n)**

 一个事件可以添加多个监听是没错,但Nodejs默认最大值是多少呢?



var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter(); /* 给EventEmitter 添加11个监听 */ for (var i = 10; i >= 0; i--) { ee.on('some_events',function() { console.log('第'+ (i +1) +'个监听'); }); };


添加N个监听示例源码   
 上面示例中我用个循环给some\_events添加11个监听,执行代码,发现warning信息出现,并且提示的比较详细了,需要用emitter.setMaxListeners()去提升限值



var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter(); /* EventEmitter.setMaxListeners (n) 给EventEmitter设置最大监听 参数1: n 数字类型,最大监听数

超过10个监听时,不设置EventEmitter的最大监听数会提示: (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 设计者认为侦听器太多,可能导致内存泄漏,所以存在这样一个警告 */ ee.setMaxListeners(15); /* 给EventEmitter 添加11个监听 */ for (var i = 10; i >= 0; i--) { ee.on('some_events',function() { console.log('第'+ (i +1) +'个监听'); }); };


当我调用emitter.setMaxListeners传入15时,执行代码,warning信息不再出现;


emitter.setMaxListeners的作用是给EventEmitter设置最大监听数,感觉一般是不需要设置这个值,10个还不够用的情况应该是比较少了!


设计者认为侦听器太多会导致内存泄漏,所有就给出了一个警告!


其它…


用的比较少的就不详细说了


* EventEmitter.defaultMaxListeners


EventEmitter.defaultMaxListeners功能与setMaxListeners类似,   
 给所有EventEmitter设置最大监听


setMaxListeners优先级大于defaultMaxListeners


### Vue

* 什么是MVVM?

* mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?

* 组件之间的传值?

* Vue 双向绑定原理

* 描述下 vue 从初始化页面–修改数据–刷新页面 UI 的过程?

* 虚拟 DOM 实现原理

* Vue 中 key 值的作用?

* Vue 的生命周期

* Vue 组件间通信有哪些方式?

* vue 中怎么重置 data?

* 组件中写 name 选项有什么作用?

* Vue 的 nextTick 的原理是什么?

* Vuex 有哪几种属性?  

  **[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://docs.qq.com/doc/DSmRnRGxvUkxTREhO)**

  ![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/bf20d3c0232348379ed5fcafc3b3e732~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1770716705&x-signature=3XCeyaiZZrcNk4XE63RQtvcvD9M%3D)

  ![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7cdcd0cb84f3410ba4b22951d5872cd2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1770716705&x-signature=IOjvK8ndBurBb%2F1ew9s5EoYKEc4%3D)