Node.js 事件触发器模块 events

简介

触发器(Emitter)类型的对象会触发命名事件来调用函数(又称监听器,Listener)。所有能触发事件的对象都是 EventEmitter 类的实例。 这些对象有一个 eventEmitter.on() 函数,用于将一个或多个函数绑定到命名事件上。 事件的命名通常是驼峰式的字符串。


当 EventEmitter 对象触发一个事件时,所有绑定在该事件上的函数都会被同步地调用。 被调用的监听器返回的任何值都将会被忽略并丢弃。


例子,一个简单的 EventEmitter 实例,绑定了一个监听器。 eventEmitter.on() 用于注册监听器, eventEmitter.emit() 用于触发事件。使用 eventEmitter.once() 可以注册最多可调用一次的监听器。 当事件被触发时,监听器会被注销,然后再调用。

const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
 console.log('触发事件');
});
myEmitter.emit('event');


将参数和 this 传给监听器

eventEmitter.emit() 方法可以传任意数量的参数到监听器函数。 当监听器函数被调用时, this 关键词会被指向监听器所绑定的 EventEmitter 实例。

const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
 console.log(a, b, this, this === myEmitter);
});
myEmitter.emit('event', 'a', 'b');

也可以使用 ES6 的箭头函数作为监听器。但 this 关键词不会指向 EventEmitter 实例:


异步 VS 同步

EventEmitter 以注册的顺序同步地调用所有监听器。 这样可以确保事件的正确排序,并有助于避免竞态条件和逻辑错误。 当适当时,监听器函数可以使用 setImmediate() 和 process.nextTick() 方法切换到异步的操作模式:

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
 setImmediate(() => {
  console.log('异步地发生');
 });
});
myEmitter.emit('event', 'a', 'b');


错误事件

当 EventEmitter 实例出错时,应该触发 'error' 事件。 这些在 Node.js 中被视为特殊情况。

如果没有为 'error' 事件注册监听器,则当 'error' 事件触发时,会抛出错误、打印堆栈跟踪、并退出 Node.js 进程。

const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('错误信息'));
// 抛出错误并使 Node.js 崩溃。


为了防止崩溃 Node.js 进程,可以使用 domain 模块。 (但请注意,不推荐使用 domain 模块。)

作为最佳实践,应该始终为 'error' 事件注册监听器

const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
 console.error('错误信息');
});
myEmitter.emit('error', new Error('错误'));
// 打印: 错误信息


通过使用符号 errorMonitor 安装监听器,可以监视 'error' 事件但不消耗触发的错误。

const myEmitter = new MyEmitter();
myEmitter.on(EventEmitter.errorMonitor, (err) => {
 MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('错误'));
// 仍然抛出错误并使 Node.js 崩溃。


捕捉 Promise 的拒绝

const ee = new EventEmitter();
ee.on('something', async (value) => {
 throw new Error('kaboom');
});


内存管理与防止泄漏

在绑定事件监听器的时候,如果监听器没有被 remove,那么存在内存泄漏的风险。


参考文档:

http://nodejs.cn/api/events.html

真诚赞赏,手留余香
赞赏
随机推荐
CentOS 安全
SQLite目前还不支持drop column
ThinkPHP5.* 远程代码执行高危漏洞的修复
Filezilla Server和防火墙设置的相关知识(主动连接和被动连接)
url-loader
Node.js 文件系统
PHP下载文件,隐藏真实文件地址
网络协议入门
jQuery Mobile弹出对话框后不刷新原页面,保持原页面内容不变
Node.js process.env 根据环境切换配置文件