Node.js EventEmitter 笔记

·  阅读 1098

说起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;
复制代码
分类:
前端
标签:
分类:
前端
标签: