Events是Node最重要的子產品,它提供了一個對象events.EventEmitter,EventEmitter 的核心是事件發射與事件監聽器。
Node.js中大部分的子產品,都繼承自Event子產品。
EventEmitter 支援若幹個事件監聽器,當事件發射時,注冊到這個事件的事件監聽器被依次調用,事件參數作為回調函數參數傳遞。
事件子產品相關的方法主要有以下這些:
1. EventEmitter.on(event, listener)
注冊監聽事件。
參數1:event 事件名;
參數2:listener 回調函數;
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 注冊監聽事件someEvents
ee.on('someEvents', function(a, b) {
console.log("觸發了監聽事件,參數為1為" + a + ",參數2為" + b );
});
// 第1次觸發事件someEvents
ee.emit('someEvents', 'time', 'address');
// 觸發了監聽事件,參數為1為time,參數2為address
// 第2次觸發事件someEvents
ee.emit('someEvents', 'name', 'age');
// 觸發了監聽事件,參數為1為name,參數2為age
複制
2. EventEmitter.emit(event, [arg1], [arg2], [...])
觸發指定的監聽事件。
參數1:event 事件名;
參數2:[arg1] 可選參數,按順序傳入回調函數的參數;
傳回值:該事件是否有監聽;
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 第1次注冊監聽事件someEvents
ee.on('someEvents', function (a, b) {
console.log("觸發了第1個監聽事件,參數為1為" + a + ",參數2為" + b);
});
// 觸發事件someEvents并傳回布爾類型的結果值
var resultA = ee.emit('someEvents', 'time', 'address');
// 觸發了第1個監聽事件,參數為1為time,參數2為address
// 第2次注冊監聽事件someEvents
ee.on('someEvents', function (a, b) {
console.log("觸發了第2個監聽事件,參數為1為" + a + ",參數2為" + b);
});
// 觸發監聽事件someEvents
ee.emit('someEvents', 'name', 'age');
// 觸發了第1個監聽事件,參數為1為time,參數2為address
// 觸發了第2個監聽事件,參數為1為time,參數2為address
// 嘗試觸發一個未注冊的監聽事件并傳回布爾類型的結果值
var resultB = ee.emit('otherEvents', 'page', 'pagesize');
console.log(resultA);
// true
console.log(resultB);
// false
複制
3. EventEmitter.once(event, listener)
為事件注冊一次性監聽,觸發一次後移除監聽事件,後續再次觸發将無效。
參數1:event 事件名;
參數2:listener 回調函數;
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 注冊一次性監聽事件someEvents
ee.once('someEvents', function(a, b) {
console.log("觸發了監聽事件,參數為1為" + a + ",參數2為" + b);
});
// 觸發一次性監聽事件
ee.emit('someEvents', 'time', 'address');
// 觸發了監聽事件,參數為1為time,參數2為address
// 再次觸發監聽事件,并傳回布爾結果值
var result = ee.emit('someEvents', 'name', 'age');
console.log(result);
// false
複制
4. EventEmitter.removeListener(event, listener)
移除指定事件的監聽器,注意:該監聽器必須是注冊過的。
參數1:event 事件名;
參數2:listener 回調函數;
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 監聽事件1
var listener1 = function(a,b){
console.log("觸發了第1個監聽事件,參數為1為" + a + ",參數2為" + b);
}
// 監聽事件2
var listener2= function(a,b){
console.log("觸發了第2個監聽事件,參數為1為" + a + ",參數2為" + b);
}
// 監聽事件3
var listener3= function(a,b){
console.log("觸發了第3個監聽事件,參數為1為" + a + ",參數2為" + b);
};
// 注冊監聽事件1
ee.on('someEvents', listener1);
// 注冊監聽事件2
ee.on('someEvents', listener2);
// 注冊監聽事件3
ee.on('someEvents', listener3);
// 移除監聽事件1
ee.removeListener('someEvents', listener1);
// 移除監聽事件2
ee.removeListener('someEvents', listener2);
// 觸發監聽事件
ee.emit('someEvents', 'time', 'address');
// 觸發了第3個監聽事件,參數為1為time,參數2為address
複制
5. EventEmitter.removeAllListeners([event])
移除(批定事件)所有監聽器,一個事件可以有多個監聽,需要全部移除時,可以用此方法。
參數1:event 事件名 可選參數。
需要特别注意的是,如果不傳參數,将會移除所有的監聽事件,比較暴力,建議慎用。
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 監聽事件1
var listener1 = function(a,b){
console.log("觸發了第1個監聽事件,參數為1為" + a + ",參數2為" + b);
};
// 監聽事件2
var listener2= function(a,b){
console.log("觸發了第2個監聽事件,參數為1為" + a + ",參數2為" + b);
};
// 注冊監聽事件1
ee.on('someEvents', listener1);
// 注冊監聽事件2
ee.on('someEvents', listener2);
// 注冊監聽另一個事件
ee.on('otherEvents',function(a,b){
console.log("觸發了另1個監聽事件,參數為1為" + a + ",參數2為" + b);
});
// 移除所有的注冊監聽事件someEvents
ee.removeAllListeners('someEvents');
// 觸發監聽事件someEvents
ee.emit('someEvents', 'time', 'address');
// 觸發另一個監聽事件otherEvents
ee.emit('otherEvents', 'name', 'age');
// 觸發了另1個監聽事件,參數為1為name,參數2為age
複制
6. EventEmitter.listeners(event)
傳回指定事件的注冊監聽的集合。
參數1:event 事件名 。
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 監聽事件1
var listener1 = function (a, b) {
console.log("觸發了第1個監聽事件,參數為1為" + a + ",參數2為" + b);
};
// 監聽事件2
var listener2 = function (a, b) {
console.log("觸發了第2個監聽事件,參數為1為" + a + ",參數2為" + b);
};
// 注冊監聽事件1
ee.on('someEvents', listener1);
// 注冊監聽事件2
ee.on('someEvents', listener2);
// 注冊監聽另一個事件
ee.on('otherEvents', function (a, b) {
console.log("觸發了另1個監聽事件,參數為1為" + a + ",參數2為" + b);
});
// 擷取指定事件的監聽數組
var listenerEventsArr = ee.listeners('someEvents');
for (var i = 0; i < listenerEventsArr.length; i++) {
// 列印輸出監聽事件
console.log(listenerEventsArr[i]);
// [Function: listener1]
// [Function: listener2]
};
複制
7. EventEmitter.setMaxListeners (n)
給EventEmitter設定最大監聽數。
參數1: n 數字最大監聽數。
正常情況下,可以設定的最大監聽數為10個,如果超過了10個,就會出現警告,以下代碼可以驗證。
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 給EventEmitter 添加11個監聽
for (var i = 0; i <= 10; i++) {
ee.on('someEvents',function(){
console.log('第'+ (i +1) +'個監聽');
});
};
複制
執行結果出現了如下的警告:
Warning: Possible EventEmitter memory leak detected. 11 someEvents listeners added. Use emitter.setMaxListeners() to increase limit。
系統認為偵聽器太多,可能導緻記憶體洩漏,是以存在這樣一個警告,并且給出了提示,讓我們用 emitter.setMaxListeners() 去提升限制。
// 調用events子產品,擷取events.EventEmitter對象
var EventEmitter = require('events').EventEmitter;
// 執行個體化EventEmitter對象
var ee = new EventEmitter();
// 設定最大監聽數為16個
ee.setMaxListeners(16);
// 給EventEmitter 添加11個監聽
for (var i = 0; i <= 10; i++) {
ee.on('someEvents',function(){
console.log('第'+ (i +1) +'個監聽');
});
};
var listenerEventsArr = ee.listeners('someEvents');
// 列印輸出監聽事件數量
console.log(listenerEventsArr.length);
// 11
複制
不知道為什麼,11個事件是添加成功了,但是回調裡沒有列印輸出,歡迎大家在評論區讨論!
8. EventEmitter.defaultMaxListeners (n)
給所有EventEmitter設定最大監聽,功能與setMaxListeners類似,不過setMaxListeners優先級要大于defaultMaxListeners,用的比較少,就不細說了。
9. EventEmitter.listenerCount(emitter, event)
傳回指定事件的監聽數,用的比較少,就不細說了。