說起Node中幾個最重要的模組,那麼events
模組一定在其中,在Node中很多很多的其他模組都是基於或者依賴於events
模組。
那麼我們來了解一下什麼是events
模組和events
模組的使用,和一些注意點
我們參看的Node v6.10.3文件, 對於EventEmitter的方法我們不解釋,相對比較簡單,官方也給出了較多的例子,完全可以參看官方的文件,這裡就說明一些注意點
EventEmitter例項化
首先很多的教程裡面會寫以下的程式碼來例項化一個EventEmitter
var events = require('events');
var emitter = new events.EventEmitter();
複製程式碼
但是官方給出的例子卻是
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
複製程式碼
在REPL
中輸出const EventEmitter = require('events');
中的EventEmitter
EventEmitter
{ [Function: EventEmitter]
EventEmitter: [Circular], // 迴圈引用
usingDomains: true,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] }
複製程式碼
同時在翻看原始碼之後看到
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
複製程式碼
所以,兩種方式都是可以的,但是感覺按照官方的方式會更好。
error事件
當 EventEmitter 例項中發生錯誤時,會觸發一個 'error' 事件。 這在 Node.js 中是特殊情況。
如果 EventEmitter 沒有為 'error' 事件註冊至少一個監聽器,則當 'error' 事件觸發時,會丟擲錯誤、列印堆疊跟蹤、且退出 Node.js 程式。
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// 丟擲錯誤,並使 Node.js 奔潰
複製程式碼
所以應該始終為 'error' 事件註冊監聽器。
myEmitter.on('error', (err) => {
console.error('有錯誤');
});
複製程式碼
另外提一句為了防止 Node.js 程式崩潰,可以在 process 物件的 uncaughtException
事件上註冊監聽器。
const myEmitter = new MyEmitter();
process.on('uncaughtException', (err) => {
console.error('有錯誤');
});
myEmitter.emit('error', new Error('whoops!'));
複製程式碼
this作用域
在ES6加入後,有了箭頭函式,有時候會導致監聽器的this
作用域的不同,這裡需要稍微注意一下
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this);
// 列印:
// a b MyEmitter {
// domain: null,
// _events: { event: [Function] },
// _eventsCount: 1,
// _maxListeners: undefined }
});
myEmitter.emit('event', 'a', 'b');
複製程式碼
箭頭函式版本
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// 列印: a b {}
});
myEmitter.emit('event', 'a', 'b');
複製程式碼
相信瞭解過箭頭函式的原理的都應該可以理解。
on()
和 addListener()
的區別
沒有區別
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
複製程式碼