Node.js事件

133 阅读2分钟

官方文档关于事件的介绍

大多数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 不会打乱对象原有的继承关系。

js实现EventEmitter类:

github.com/fortheallli…