Nodejs study notes (2) - event module

1. Introduction and information

   http://nodejs.org/api/events.html

   http://www.infoq.com/cn/articles/tyq-nodejs-event

        Events is the most important module of node.js. The events module only provides an object events.EventEmitter. The core of EventEmitter is event emission and event listener.

        Most modules in Node.js inherit from the Event module.

        Unlike events on the DOM tree, there is no such behavior as event bubbling and layer-by-layer capture.

        EventEmitter supports several event listeners. When an event is emitted, the event listeners registered to this event are called in turn, and the event parameters are passed as callback function parameters.   

        How to access: require('events');

 

二.emitter.on(event, listener)

/*
    Call the events module to get the events.EventEmitter object
*/
var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

/*
    EventEmitter.on(event, listener) register a listener for the event
    Parameter 1: event string, event name
    Parameter 2: callback function
*/
ee.on('some_events', function(foo, bar) {
    console.log("The first listening event, parameter foo=" + foo + ", bar="+bar );
});

console.log('');
ee.emit('some_events', 'Wilson', 'Zhong');

console.log('Second round');
ee.emit('some_events', 'Wilson', 'Z');

        In Sublime, run Ctrl+B directly, as shown below:


        Of course, it can also be executed in the cmd window, as follows:



三.emitter.emit(event, [arg1], [arg2], [...])

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

ee.on('some_events', function(foo, bar) {         
    console.log("The first listening event, parameter foo=" + foo + ", bar="+bar );
});

/*
    EventEmitter.emit(event, [arg1], [arg2], [...]) trigger the specified event
    Parameter 1: event string, event name
    Parameter 2: optional parameters, parameters passed to the callback function in order
    Return value: whether the event is monitored
*/
var isSuccess = ee.emit('some_events', 'Wilson', 'Zhong');

ee.on('some_events', function(foo, bar) {         
    console.log("The second listening event, parameter foo=" + foo + ", bar="+bar );
});

ee.emit('some_events', 'zhong', 'wei');

var isSuccess2 = ee.emit('other_events', 'Wilson', 'Zhong');

console.log(isSuccess);
console.log(isSuccess2);


        The example triggers event operations three times, in which some_events is registered for monitoring, the emit function will return a true when called, while other_events is not registered for monitoring, the emit function will return a false, indicating that the event is not monitored; of course, you can ignore this return value!

 

四.emitter.once(event, listener)

 

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

/*
    EventEmitter.once(event, listener) Register a one-time listener for the event, and remove the listener after it is triggered once
    Parameter 1: event string, event name
    Parameter 2: callback function
*/
ee.once('some_events', function(foo, bar) {
    console.log("The first listening event, parameter foo=" + foo + ", bar="+bar );
});


console.log('First round');
ee.emit('some_events', 'Wilson', 'Zhong');

console.log('Second round');
var isSuccess =  ee.emit('some_events', 'Wilson', 'Zhong');
console.log(isSuccess);

        As can be seen from the execution results of the above example code, after registering a listener for some_events with emitter.once, the emitter.emit is called in two rounds to trigger the trigger, and the second round will return false; this means that the emitter.once is used to register the listener and use the aforementioned The emitter.on registration monitor is slightly different. The emitter.once registration monitor is a one-time monitor. When triggered once, the monitor will be removed! Of course, it's more obvious from the name ^_^!

 

 

五.emitter.removeListener(event, listener)

        Let's take a look at a failed scene~~~

 

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

ee.on('some_events', function(foo, bar) {
    console.log("The first listening event, parameter foo=" + foo + ", bar="+bar );
});

/*
    When I saw the removeListener removal method in the API, I thought it should be like this
    But the result ^_^!!!!!
*/
ee.removeListener('some_events', function(){
    console.log('Successfully removed the event some_events listener!');        
});

console.log('First round');
ee.emit('some_events', 'Wilson', 'Zhong');

 

        当我用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: After the last example, it will fail. The big reason is that the listener is ignored. It is a matter of course that it is OK to pass an event name, so it is a tragedy!
*/
ee.removeListener('some_events', listener);

ee.removeListener('some_events', listener3);

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

        I used the writing method in the example to add three listeners to some_events, remove the first and third listeners, and finally use emitter.emit to trigger some_events. It is not difficult to find the output result. Neither the first nor the third monitor works anymore,

 

        Of course it is harmful, the second parameter of the original emitter.removeListener is the listener to be removed, not the callback function after successful removal... ^_^!

 

六.emitter.removeAllListeners([event])

        The emitter.removeListener has been used, but an event can have multiple listeners. When all of them need to be removed, it is obviously not a pleasant practice to remove them one by one, and it does not conform to the lazy nature!

        Let's experience the convenience brought by emitter.removeAllListeners!

 

var EventEmitter = require('events').EventEmitter;   
var ee = new EventEmitter();

var listener = function(foo,bar)
{
    console.log("The first listening event, parameter foo=" + foo + ", bar="+bar );
}

var listener2 = function (foo, bar)
{
    console.log("The second listening event, parameter foo=" + foo + ", bar="+bar );
}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('other_events',function(foo,bar)
{
    console.log("Other listening events, parameter foo=" + foo + ", bar="+bar );
});

/*
    EventEmitter.removeAllListeners([event]) remove (batch event) all listeners
    Parameter 1: optional parameter, event string, event name
*/
ee.removeAllListeners('some_events');

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

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

        Looking at the above execution results, you will find that two listeners are registered for some_events; one listener is registered for other_events; I call emitter.removeAllListeners and pass some_events event name;

 

        Finally, the emitter.on function is used to trigger two events, some_events and other_events. Finally, it is found that the two listeners registered by some_events do not exist, and the listener registered by other_events still exists;

        This means that when emitter.removeAllListeners is passed the event name as a parameter, all listeners with the incoming event name will be removed without affecting other event listeners!

        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所有监听都不存在了,它会移除所有监听!(比较暴力的方法一般要慎用~~)

 

七.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]); 
};

 

        给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) +'个监听');
    });
};


        上面示例中我用个循环给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个还不够用的情况应该是比较少了!

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

 

九.其它

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

1.EventEmitter.defaultMaxListeners

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

setMaxListeners优先级大于defaultMaxListeners。

2.EventEmitter.listenerCount(emitter, event)

        返回指定事件的监听数

3.特殊的事件Error

        Quoted from the Node.js Development Guide: EventEmitter defines a special event error, which contains the semantics of "error", and we usually emit the error event when we encounter an exception. When an error is emitted, the EventEmitter specifies that if there is no responding listener, Node.js will treat it as an exception, exit the program and print the call stack. We generally set up listeners for objects that emit error events to avoid crashing the entire program after encountering errors.

4. Inheritance of events

        If you are interested, you can take a look yourself: http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor

 

Article source: http://www.cnblogs.com/zhongweiv/p/nodejs_events.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326780625&siteId=291194637