Node中的Events模块介绍及应用_node.js

来源:脚本之家  责任编辑:小易  
目录
Node 中的 Events1. 事件和监听器2. 处理 error 事件3. 继承 Events 模块4. 手写 EventEmitter

Node 中的 Events

Node 的 Events 模块只定义了一个类,就是 EventEmitter(以下简称 Event ),这个类在很多 Node 本身以及第三方模块中大量使用,通常是用作基类被继承。

在 Node 中,事件的应用遍及代码的每一个角落。

1. 事件和监听器

Node 程序中的对象会产生一系列的事件,它们被称为事件触发器(event emitter),例如一个 HTTP Server 会在每次有新连接时触发一个事件,一个 Readable Stream 会在文件打开时触发一个事件等。

所有能触发事件的对象都是 EventEmitter 类的实例。EventEmitter 定义了 on 方法,该方法的声明如下:

emitter.on(eventName, listener)
eventName <String> | <Symbol> The name of the event.
listener <Function> The callback function

on 方法接受两个参数:需要监听的事件的名称,当事件触发时需要调用的函数。因为 EventEmitter 是接口,从 EventEmitter 继承的类需要使用 new 关键字来构造。

触发事件监听器很简单,只要调用 EventEmitter实例的 emit 方法就行了。需要注意的是,这些事件是针对某个实例的,不存在全局的事件。当你调用 on 方法的时候,需要绑定在特定的基于 EventEmitter 的对象上。EventEmitter 类不同的实例之间也不会共享事件。

下面是一个事件注册和触发事件的例子。

const eventEmitter = require('events');
const myEmitter = new eventEmitter();
myEmitter.on('begin', () => {
  console.log('begin');
});
myEmitter.emit('begin');

上面的代码中,首先初始化了一个 EventEmitter 实例,然后注册了一个名为 begin 的事件,之后调用 emit 方法触发了这一事件。

用户可以注册多个同名的事件,在上面的例子中,如果注册两个名为 begin 的事件,那么它们都会被触发。

如果想获取当前的 emitter 一共注册了哪些事件,可以使用 eventNames 方法。

console.log(myEmitter.eventNames());

该方法会输出包括全部事件名称的数组。就算注册了两个同名的 event,输出结果也只有一个,说明该方法的结果集并不包含重复结果。

2. 处理 error 事件

由于 Node 代码运行在单线程环境中,那么运行时出现的任何错误都有可能导致整个进程退出。利用事件机制可以实现简单的错误处理功能。

当 Node 程序出现错误的时候,通常会触发一个错误事件,如果代码中没有注册相应的处理方法,会导致 Node 进程崩溃退出。例如:

myEmitter.emit("error", new Error("crash!"));

上面的代码主动抛出了一个 emor,相当于:

throw new Error ("crash");

如果我们不想因为抛出一个 error 而使进程退出,那么可以让 uncaughtException 事件作为最后一道防线来捕获异常。

const eventEmitter = require('events');
const myEmitter = new eventEmitter();
process.on('uncaughtException', () => {
  console.log('got error');
});
throw new Error('Error occurred');

这种错误处理的方式虽然可以捕获异常,避免了进程的退出,但不值得提倡。

关于其常见的方法如下:

emitter.addListener/on(eventName, listener) :添加类型为 eventName 的监听事件到事件数组尾部emitter.prependListener(eventName, listener):添加类型为 eventName 的监听事件到事件数组头部emitter.emit(eventName[, ...args]):触发类型为 eventName 的监听事件emitter.removeListener/off(eventName, listener):移除类型为 eventName 的监听事件emitter.once(eventName, listener):添加类型为 eventName 的监听事件,以后只能执行一次并删除emitter.removeAllListeners([eventName]): 移除全部类型为 eventName 的监听事件

3. 继承 Events 模块

在实际的开发中,通常不会直接使用 Event 模块来进行事件处理,而是选择将其作为基类进行继承的方式来使用 Event,在 Node 的内部实现中,凡是提供了事件机制的模块,都会在内部继承 Event 模块。

4. 手写 EventEmitter

下面我们来看看如何手写一个 EventEmitter

class EventEmitter {
  constructor() {
    this.events = {};
  }
  on(type, handler) {
    if (!this.events[type]) {
      this.events[type] = [];
    }
    this.events[type].push(handler);
  }
  addListener(type, handler) {
    this.on(type, handler)
  }
  prependListener(type, handler) {
    if (!this.events[type]) {
      this.events[type] = [];
    }
    this.events[type].unshift(handler);
  }
  removeListener(type, handler) {
    if (!this.events[type]) {
      return;
    }
    this.events[type] = this.events[type].filter(item => item !== handler);
  }
  off(type, handler) {
    this.removeListener(type, handler)
  }
  emit(type, ...args) {
    this.events[type].forEach((item) => {
      Reflect.apply(item, this, args);
    });
  }
  once(type, handler) {
    this.on(type, this._onceWrap(type, handler, this));
  }
  _onceWrap(type, handler, target) {
    const state = {
      fired: false,
      handler,
      type,
      target
    };
    const wrapFn = this._onceWrapper.bind(state);
    state.wrapFn = wrapFn;
    return wrapFn;
  }
  _onceWrapper(...args) {
    if (!this.fired) {
      this.fired = true;
      Reflect.apply(this.handler, this.target, args);
      this.target.off(this.type, this.wrapFn);
    }
  }
}

到此这篇关于Node中的Events事件介绍及应用的文章就介绍到这了,更多相关Node Events内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网!

您可能感兴趣的文章:Node.js中的events事件模块知识点总结node.JS事件机制与events事件模块的使用方法详解node.js中事件触发器events的使用方法实例分析node.js学习之事件模块Events的使用示例详解Node.js:events事件模块

  • 本文相关:
  • nodejs微信扫码支付功能实现
  • node跨域转发 express+http-proxy-middleware的使用
  • 详解nodejs之二进制buffer对象
  • 详解nodejs微信公众号开发——4.自动回复各种消息
  • express + session 实现登录验证功能
  • nodejs爬虫的技术点总结
  • 详解express与koa中间件模式对比
  • node命令行工具之实现项目工程自动初始化的标准流程
  • node基于express框架操作mysql数据库的步骤
  • node.js中的http.request方法使用说明
  • 跟我学Nodejs(二)--- Node.js事件模块
  • 详解Node.js异步处理的各种写法
  • 详解Node.js中的事件机制
  • 深入理解Node.js 事件循环和回调函数
  • 总结Node.js中的一些错误类型
  • Node.js入门先学什么
  • 深入浅析Node.js 事件循环
  • 如何在 Windows 10 中搭建 Node.js 环境
  • 记录几个node.js错误及解决方案
  • 如何在 Windows 10 中搭建 Node.js 环境
  • Node.js使用对话框ngDialog的示例代码
  • 如何在一个react模块组件里引入嵌套另一个react模块组件
  • 如何调用module.exports类中的其他方法
  • Nodejs学习item【入门手上】
  • 什么是事件循环
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全基础知识javascript类库表单特效广告代码网页特效黑客性质javascript技巧domnode.jsjs其它首页javascriptnode.jsnode.js中的events事件模块知识点总结node.js事件机制与events事件模块的使用方法详解node.js中事件触发器events的使用方法实例分析node.js学习之事件模块events的使用示例详解node.js:events事件模块nodejs微信扫码支付功能实现node跨域转发 express+http-proxy-middleware的使用详解nodejs之二进制buffer对象详解nodejs微信公众号开发——4.自动回复各种消息express + session 实现登录验证功能nodejs爬虫的技术点总结详解express与koa中间件模式对比node命令行工具之实现项目工程自动初始化的标准流程node基于express框架操作mysql数据库的步骤node.js中的http.request方法使用说明一行命令搞定node.js 版本升级卸载安装node.js与npm过程详解yarn的安装与使用详细介绍node.js中的fs.writefilesync方法使用说windows如何把已安装的nodejs高版本降级为低版本(使用npm命令提示: ""npm"" 不是内部或外部命令,也node.js(安装,启动,测试)nodejs中调用系统命令、shell脚本和python脚本node.js+ajax实现获取http服务器返回数据node.js中环境变量process.env的一些事详解nodejs使用七牛云存储上传文件的方法node.js 基于cheerio的爬虫工具的实现(需要登录权限的爬虫工具)node.js中的fs.appendfilesync方法使用说明node.js中读取txt文件内容fs.readfile()用法初识node.jskoa2微信公众号开发之本地开发调试环境搭建node.js 服务器端应用开发框架 -- hapi.js深入了解node.js中的一些特性利用node.js搭建简单web服务器的方法教程nodejs初级阶段之express
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved