이벤트는 node.js의 가장 중요한 모듈입니다. 이벤트 모듈은 하나의 객체 events.EventEmitter만 제공합니다. 🎜> 이벤트 방출 및 이벤트 리스너.
Node.js의 대부분의 모듈은 이벤트 모듈에서상속됩니다.
DOM 트리의 이벤트와 달리 이벤트 버블링이나 레이어별 캡처와 같은동작이 없습니다.
EventEmitter는 여러 이벤트 리스너를 지원합니다. 이벤트가 발생하면 해당 이벤트에 등록된 이벤트 리스너가 차례로 호출되며, 이벤트 매개변수는콜백 함수 매개변수로 전달됩니다.
접속 방법: 코드는 다음과 같습니다:require('events');
emitter.on(event,listener)
/* 调用events模块,获取events.EventEmitter对象 */ var EventEmitter = require('events').EventEmitter; var ee = new EventEmitter(); /* EventEmitter.on(event, listener) 为事件注册一个监听 参数1:event 字符串,事件名 参数2:回调函数 */ ee.on('some_events', function(foo, bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); }); console.log('第一轮'); ee.emit('some_events', 'Wilson', 'Zhong'); console.log('第二轮'); ee.emit('some_events', 'Wilson', 'Z'); EventEmitter.on(event, listener) 示例源码
emitter.emit(event, [arg1], [arg2], [...])
var EventEmitter = require('events').EventEmitter; var ee = new EventEmitter(); ee.on('some_events', function(foo, bar) { console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar ); }); /* EventEmitter.emit(event, [arg1], [arg2], [...]) 触发指定事件 参数1:event 字符串,事件名 参数2:可选参数,按顺序传入回调函数的参数 返回值:该事件是否有监听 */ 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); emitter.emit(event, [arg1], [arg2], [...]) 示例源码
emitter.once(event,listener)
var EventEmitter = require('events').EventEmitter; var ee = new EventEmitter(); /* EventEmitter.once(event, listener) 为事件注册一次性监听,触发一次后移除监听 参数1:event 字符串,事件名 参数2:回调函数 */ 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(event, listener) 示例源码
emitter.removeListener(event,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.removeListener(event, listener) 示例失败场景源码
代码如下:
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'); emitter.removeListener(event, listener) 示例成功场景源码
我用示例中写法,给some_events添加了三个监听,又移除了第一个和第三个监听,最后再用emitter.emit触发some_events,输出结果不难发现,用emitter.removeListener移除的第一个和第三个监听都没有再起作用,
想当然是害人地,原来emitter.removeListener的第二个参数是要移除的监听,而非移除成功后的回调函数……^_^!
emitter.removeAllListeners([event])
emitter.removeListener用过了,但一个事件可以有多个监听,需要全部移除时,一个个移除明显不是愉快的做法,不符合偷懒的天性!
让我们来体验一下emitter.removeAllListeners带来的便捷!
代码如下:
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 ); }); /* EventEmitter.removeAllListeners([event]) 移除(批定事件)所有监听器 参数1:可选参数,event 字符串,事件名 */ ee.removeAllListeners('some_events'); ee.emit('some_events', 'Wilson', 'Zhong'); ee.emit('other_events', 'Wilson', 'Zhong'); emitter.removeAllListeners 传入事件名参数示例源码
看看上面的执行结果,你会发现给some_events注册了两个监听;给other_events注册了一个监听;我调用emitter.removeAllListeners传了some_events事件名;
最后使用emitter.on函数触发some_events和other_events两个事件,最后发现some_events注册的两个监听都不存在,而other_events注册的监听还存在;
这表示当 emitter.removeAllListeners传用事件名作为参数时,为移除传入事件名的所有监听,而不会影响其它事件监听!
emitter.removeAllListeners可以不传用事件名参数;直接执行
代码如下:
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 ); }); /* EventEmitter.removeAllListeners([event]) 移除(批定事件)所有监听器 参数1:可选参数,event 字符串,事件名 */ ee.removeAllListeners(); ee.emit('some_events', 'Wilson', 'Zhong'); ee.emit('other_events', 'Wilson', 'Zhong'); emitter.removeAllListeners 不传参数示例源码
示例代码和传入参数时几乎一样,只是在调用emitter.removeAllListeners并没有传入指定事件名;
运行结果会发现some_events和other_events所有监听都不存在了,它会移除所有监听!(比较暴力的方法一般要慎用~~)
emitter.listeners(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 ); }); /* EventEmitter.listeners(event) //返回指定事件的监听数组 参数1:event 字符串,事件名 */ var listenerEventsArr = ee.listeners('some_events'); console.log(listenerEventsArr.length) for (var i = listenerEventsArr.length - 1; i >= 0; i--) { console.log(listenerEventsArr[i]); }; emitter.listeners(event) 示例源码
给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 示例源码
当我调用emitter.setMaxListeners传入15时,执行代码,warning信息不再出现;
emitter.setMaxListeners的作用是给EventEmitter设置最大监听数,感觉一般是不需要设置这个值,10个还不够用的情况应该是比较少了!
设计者认为侦听器太多会导致内存泄漏,所有就给出了一个警告!
其它...
用的比较少的就不详细说了
EventEmitter.defaultMaxListeners
EventEmitter.defaultMaxListeners功能与setMaxListeners类似,
给所有EventEmitter设置最大监听
setMaxListeners优先级大于defaultMaxListeners
EventEmitter.listenerCount(emitter, event)
返回指定事件的监听数
特殊的事件Error
引用自Node.js开发指南:EventEmitter 定义了一个特殊的事件 error,它包含了“错误”的语义,我们在遇到 异常的时候通常会发射 error 事件。当 error 被发射时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并打印调用栈。我们一般要为会发射 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。
事件的继承
以上就是跟我学Nodejs(二)-Node.js事件模块的内容,更多相关内容请关注PHP中文网(www.php.cn)!