nodejs系列:12.node的events模块

157 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

系列介绍

该系列主要是介绍一些nodejs相关的基础知识,没有什么特别难的知识点,都是一些比较基础知识点。大家学习起来,也会比较容易理解和接收。

这些知识点,也是以前自己学习nodejs的时候,学习过的知识点。有些知识点,可能是由于学习的时间比较久了,也有可能是平时工作中用到的机会比较少,也差不多快把它们都忘记掉了。现在把它们都写下来,写成文章,一方面是记录下自己以前学习的nodejs知识点,一方面也是复习巩固自己以前学习的nodejs知识点。不要学着学着,就把以前的知识点都忘光了。

nodejs介绍

nodejs摘抄过来的node介绍:

Node.js 是一个开源和跨平台的 JavaScript 运行时环境。 它几乎是任何类型项目的流行工具!

Node.js 在浏览器之外运行 V8 JavaScript 引擎(Google Chrome 的内核)。 这使得 Node.js 的性能非常好。

Node.js 应用程序在单个进程中运行,无需为每个请求创建新的线程。 Node.js 在其标准库中提供了一组异步的 I/O 原语,以防止 JavaScript 代码阻塞,通常,Node.js 中的库是使用非阻塞范式编写的,使得阻塞行为成为异常而不是常态。

当 Node.js 执行 I/O 操作时(比如从网络读取、访问数据库或文件系统),Node.js 将在响应返回时恢复操作(而不是阻塞线程和浪费 CPU 周期等待)。

这允许 Node.js 使用单个服务器处理数千个并发连接,而不会引入管理线程并发(这可能是错误的重要来源)的负担。

Node.js 具有独特的优势,因为数百万为浏览器编写 JavaScript 的前端开发者现在无需学习完全不同的语言,就可以编写除客户端代码之外的服务器端代码。

在 Node.js 中,可以毫无问题地使用新的 ECMAScript 标准,因为你不必等待所有用户更新他们的浏览器,你负责通过更改 Node.js 版本来决定使用哪个 ECMAScript 版本,你还可以通过运行带有标志的 Node.js 来启用特定的实验性功能。

我们可以从介绍里面看到,nodejs还是挺棒的。

nodejs遵循的是commomjs规范,所以使用nodejs的时候,需要按照commomjs规范来编写代码。

环境安装

实现之前,你首先需要安装nodejs环境。因为我们写的代码需要在node环境上运行,如果你没有,那么文件会运行不了。

以下是nodejs的安装地址,如果你没有安装的话,可以先把它安装上。安装了可以忽略这一步,跳到下面一步。

nodejs安装

前言

在nodejs系列前面几篇文章中,我们介绍了好几个模块:http模块、url模块、querystring、path模块等。接下来,我们还要介绍nodejs里面常用的一个模块events模块。

events模块是什么?

node中,采用的是事件驱动机制。node的内置模块events,它有一个类EventEmitter,该类就是node实现事件驱动的基础。

在EventEmitter的基础之上,node几乎所有的模块都继承了这个类,以实现异步事件驱动架构。

模块继承于EventEmitter,可以自定义自己的事件。利用绑定/触发监听器,来实现异步操作。

EventEmitter是node事件模型的根基,是我们平时在nodejs中开发异步编程思想的一种实现。

使用

下面,我们通过一些示例,来看下我们怎么使用events模块。

先创建一个index.js文件,引入events模块

const events = require('events')

实例化一个EventEmitter实例对象出来。


let emiter = new events.EventEmitter()

接着分别介绍一下EventEmitter各个方法

on

EventEmitter的on方法,可以监听一个事件。当该事件触发时,就会执行它绑定的回调函数。类似我们开发网页时,dom的点击事件一样。


emiter.on('getName',function(){
    console.log('getName事件触发了');
})
emit

EventEmitter实例对象监听了一个事件,那这个事件怎么触发呢?

这时,就要用到EventEmitter的另外一个方法emit,使用emit,可以触发对应事件


emiter.emit('getName')

在cmd里,用node运行index.js文件,查看打印日志

0001.png

我们可以看到,getName事件触发了

触发事件的时候,能否传递参数?

可以传递参数,在emit方法里,传递想要传递的参数。在监听事件的回调函数里,接收参数即可


emiter.on('getName',function(name){
    console.log(`我的名字是${name}`);
})
emiter.emit('getName','alin')

在cmd里,用node运行index.js文件,查看打印日志

0002.png

我们可以看到,传递的参数alin被打印出来了

once

在我们开发的时候,可能会遇到这种场景:有些事件,我们只让它触发一次就好。那怎么做呢?

EventEmitter的once方法,就可以帮我们做到。它监听指定事件,让该事件的回调函数只执行一次,后续不会再执行。


emiter.once('say',function(){
    console.log('打个招呼');
})
emiter.emit('say')
emiter.emit('say')

在cmd里,用node运行index.js文件,查看打印日志

0003.png

在日志里,我们可以看到,say事件触发了两次,但是只打印了一次。

removeListener

事件可以被监听,那怎么移除事件监听呢?

EventEmitter的removeListener方法,就可以移除事件的监听


emitter.removeListener(events,callback)

参数详解:

  • events:监听的事件
  • callback:想要移除事件哪个回调函数

示例:

上面的监听事件,我们改造一下


emiter.on('getName',getNameHandle)
function getNameHandle(){
    console.log('getName事件触发了');
}
emiter.emit('getName')
emiter.removeListener('getName',getName)
emiter.emit('getName')

在cmd里,用node运行index.js文件,查看打印日志

0001.png

从打印日志,我们可以看到,getNameHandle方法当getName事件触发时,执行了一次。

然后用removeListenergetNameHandle回调函数移除掉,再触发getName事件,getNameHandle没有执行了。

removeAllListener

当我们用EventEmitter监听了许多事件,我们想要移除这些事件的监听,使用removeListener方法,一个一个事件去移除监听吗?

当监听事件数量比较多时,这就会很消耗时间。

所幸,EventEmitter给我们提供了一个方法removeAllListener,帮助我们解决这个问题。

removeAllListener,可以移除EventEmitter实例对象所有监听事件。

示例:


emiter.on('getName',function(){
    console.log('getName事件触发了');
})
emiter.on('say',function(){
    console.log('打个招呼');
})
emiter.removeAllListeners()
emiter.emit('getName')
emiter.emit('say')

先是监听getNamesay两个事件。

然后又使用EventEmitter的removeAllListener方法,把监听的事件都移除掉。

接着,分别触发两个事件。

在cmd里,用node运行index.js文件,查看打印日志 0004.png 从打印日志里,我们可以看到,两个事件都没有触发。

小结

node的内置模块events模块里,有一个EventEmitter类。EventEmitter类是node实现事件驱动的基础。

EventEmitter类有以下几个方法:

  • on:监听事件
  • emit:触发事件
  • once:触发监听事件时,它的回调函数只执行一次
  • removeListener:移除监听事件指定回调函数
  • removeAllListener:移除所有监听事件

最后,放上自己比较喜欢的一句诗句:

千淘万漉虽辛苦,吹尽狂沙始到金 - 唐 刘禹锡《浪淘沙》