nodejs에서 이벤트 모듈 "events"는 이벤트 방출과 이벤트 리스너가 핵심인 "EventEmitter" 객체 하나만 제공합니다. 이 객체는 여러 이벤트 리스너를 지원합니다. 이벤트가 발생하면 이 이벤트에 등록된 이벤트 리스너가 순서대로 호출되고 이벤트 매개변수가 콜백 함수 매개변수로 전달됩니다.
이 튜토리얼의 운영 환경: windows7 시스템, nodejs 버전 12.19.0, Dell G3 컴퓨터.
events는 node.js의 가장 중요한 모듈입니다. 이벤트 모듈은 events.EventEmitter라는 하나의 객체만 제공합니다. EventEmitter의 핵심은 이벤트 방출과 이벤트 리스너입니다.
Node.js의 대부분의 모듈은 이벤트 모듈에서 상속됩니다.
DOM 트리의 이벤트와 달리 이벤트 버블링, 레이어별 캡처 등이 없습니다.
EventEmitter는 여러 이벤트 리스너를 지원합니다. 이벤트가 발생하면 해당 이벤트에 등록된 이벤트 리스너가 차례로 호출되고, 이벤트 매개변수가 콜백 함수 매개변수로 전달됩니다.
액세스 방법:
require('events');
/* 调用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');
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);
예제 세 가지 트리거 이벤트 작업이 수행되었으며 그 중 some_events가 리스너를 등록했습니다. 호출되면 내보내기 함수는 true를 반환하고 other_events는 리스너를 등록하지 않았으므로 해당 이벤트가 아님을 나타내는 false를 반환합니다. 물론 이 반환 값을 무시할 수도 있습니다.
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를 사용하여 some_events에 대한 리스너를 등록한 후 두 라운드에 걸쳐 Emitter.emit가 호출됩니다. 두 번째 라운드는 false를 반환합니다. 즉, Emitter.once를 사용하여 모니터를 등록하는 것은 앞에서 언급한 Emitter.on을 사용하여 모니터를 등록하는 것과 약간 다릅니다.
emitter.once를 사용하여 모니터를 등록하는 것은 일회성 모니터입니다. . 한번 발동되면 모니터가 제거됩니다! 물론 이름으로 보면 더 알겠지만^_^!
먼저 실패 시나리오를 살펴보겠습니다~~~
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');
After Emitter를 사용할 때 .on에서 some_events에 대한 리스너를 등록하고, emiiter.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에 3개의 모니터를 추가하고, 첫 번째와 세 번째 모니터를 제거하고, 마지막으로 Emitter.emit을 사용하여 some_events를 트리거합니다. Emitter.removeListener로 제거된 첫 번째 및 세 번째 리스너가 더 이상 작동하지 않는다는 것을 출력 결과에서 찾는 것은 어렵지 않습니다. 물론 이는 해롭다는 것이 밝혀졌습니다. 성공적인 제거 후 콜백 함수...^_^!
emitter.removeAllListeners([event])
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');위의 실행 결과를 보면 두 개의 리스너가 some_events에 등록되어 있고 한 리스너는 other_events에 등록되어 있음을 알 수 있습니다. some_events 이벤트 이름을 전달했습니다.
마지막으로, some_events 및 other_events 이벤트를 트리거하는 데 Emitter.on 함수가 사용되었습니다. 마지막으로 some_events에 의해 등록된 두 개의 리스너는 존재하지 않지만 other_events에 의해 등록된 리스너는 여전히 존재하는 것으로 나타났습니다.
즉, 이미터가 .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并没有传入指定事件名;
运行结果会发现some_events和other_events所有监听都不存在了,它会移除所有监听!(比较暴力的方法一般要慎用~~)
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]); };
给some_events注册两个监听,调用emitter.listeners函数,传入some_events事件名,接收函数返回值;
从结果可以看出,返回值接收到some_events所有注册监听的集合!
一个事件可以添加多个监听是没错,但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
EventEmitter.listenerCount(emitter, event)
返回指定事件的监听数
特殊的事件Error
引用自Node.js开发指南:EventEmitter 定义了一个特殊的事件 error,它包含了“错误”的语义,我们在遇到 异常的时候通常会发射 error 事件。当 error 被发射时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并打印调用栈。我们一般要为会发射 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。
事件的继承
以后归到util里再讲一下吧,有兴趣的可以自已看看 http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor
【推荐学习:《nodejs 教程》】
위 내용은 nodejs의 이벤트 모듈에서 제공되는 객체는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!