Node中的Events模块介绍及应用

Node中的Events模块介绍及应用

目录

Node 中的 Events

1. 事件和监听器

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内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    node 服务器端启动

    node 服务器端启动,远程桌面,设置为,场景: 根据资料学习,制作了一个web聊天室的应用,部署在windows服务器上,运行正常,当关闭远程桌面,运营node

    创业做网站选择用node好还是php

    创业做网站选择用node好还是php,语言,页面,如果你所开发的是一个PHP网站的前端页面或模板,PHP和Python语言都相对比较简单,所以虽然PHP语

    1-14node中的commonjs规范的实现

    1-14node中的commonjs规范的实现,模块,文件,node中的模块 1.内置模块、核心模块 2.第三方模块 commander/co 3.文件模块es6Module“静态”

    node express返回json数据给前端

    node express返回json数据给前端,上传,格式,请注意,使用res.json()的格式1.前面不能添加 res.writeHead(200, {‘content-type‘: ‘text/

    nodejs如何升级到最新稳定版本

    nodejs如何升级到最新稳定版本,版本,安装,命令,最新,升级,最新版本,Node.js是一种开源的、跨平台的JavaScript运行环境,它使用了Google V8引擎来

    一文带你深入了解Node.js(图文详解)

    一文带你深入了解Node.js(图文详解),模块,中间件,路由,描述,插入图片,服务器,本篇文章通过超多代码和图解来带大家深入解析Node.js,主要内容包括模

    怎么删除nodejs

    怎么删除nodejs,删除,卸载,选择,鼠标,教程,文件,删除nodejs的方法:1、打开“控制面板”,点击“卸载程序”;2、在“卸载或更改程序”界面,找到并选中

    nodejs怎么查看版本(三种方法)

    nodejs怎么查看版本(三种方法),版本,版本信息,查看,方法,命令行,系统,Node.js 是一个非常流行的开源 JavaScript 运行时环境,它可以运行在多个平台

    nodejs怎么安装?详细步骤介绍

    nodejs怎么安装?详细步骤介绍,安装,模块,输入,命令,系统,版本,随着互联网的不断发展,越来越多的前端开发者开始学习 Node.js。Node.js 它是一个基

    nodejs如何更新(4种方法)

    nodejs如何更新(4种方法),更新,安装,版本,命令,安装程序,命令行,Node.js是一个开放源代码的跨平台JavaScript运行环境,它在不同的平台上都得到了广

    详解Node怎么卸载?【步骤分享】

    详解Node怎么卸载?【步骤分享】,删除,文件,卸载,环境变量,查看,系统,Node怎么卸载?下面本篇文章给大家分享Node卸载超详细步骤,跟着本文一步步卸载

    [Curator] Node Cache 的使用与分析

    [Curator] Node Cache 的使用与分析,缓存,节点,Node Cache 使用节点数据作为本地缓存使用。这个类可以对节点进行监听,能够处理节点的增删