官方文档关于事件的介绍
大多数node.js核心API都是围绕异步的事件驱动构建的,包含emitters的对象会触发被叫做‘listeners’的事件。例如,net.Server对象,当每次连接的时候,都会触发一个事件;fs.ReadStream对象,当文件打开时,也会触发一个事件;当一个stream对象数据可读时,也会触发一个事件。
所有emit events对象都是events.EventEmitter class的实例,这些对象暴露出一个eventEmitter.on()监听自定义的事件。
const EventEmitter = require('evnets');
class MyEmitter extends EventEmitter {};
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');
事件回调this === EventEmitter的实例
const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
console.log(a, b, this === myEmitter);
// Prints: a b true
});
myEmitter.emit('event', 'a', 'b');
error事件
EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。当 error 被触发时,EventEmitter 规定如果没有响 应的监听器(listeners),Node.js会把它当作异常,退出程序并输出错误信息。我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:
var events = require('events');
var emitter = new events.EventEmitter();
emitter.emit('error')
这段代码只触发error,但是没有为它添加监听器,所以会报错。
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Uncaught, unspecified 'error' event.
at EventEmitter.emit (events.js:50:15)
at Object.<anonymous> (/home/byvoid/error.js:5:9)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Array.0 (module.js:479:10)
at EventEmitter._tickCallback (node.js:192:40)
最佳做法是,给error事件添加监听器
const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Prints: whoops! there was an error
核心组件都继承自EventEmitter
大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。 为什么要这样做呢?原因有两点: 首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。 其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。