NodeJS事件模块和EventEmitter

时间:2020-02-23 14:41:10  来源:igfitidea点击:

我们已经在以前的文章中讨论过Node JS Architecture。
NodeJS遵循事件驱动单线程方法。
请仔细阅读我以前的文章:" Node JS单线程事件循环体系结构"和" Node JS FileSystem IO程序包",因为我们将在此Events模块示例中使用FS模块知识。

我们将在本文中与一些合适的示例一起讨论Node JS Platform的"事件"模块和EventEmitter类。

NodeJS事件模块

Node JS平台遵循事件驱动编程模型。
它遵循观察者设计模式来处理事件。
在Node JS应用程序中,每个操作都会生成一个事件。
它具有一些事件处理程序来处理这些事件。

例如:-以Node JS FS(文件系统)模块为例。
当Node JS应用程序尝试打开文件时,它将生成一个事件。
如果完成使用ReadStream从文件中读取数据,则它将生成另一个事件。
如果完成使用WriteStream将数据写入文件中,则它将生成另一个事件。
这样,Node JS应用程序中的每个动作都会生成一个事件。

然后,谁负责产生这些事件?谁负责处理这些事件?我们将在本文中很快详细讨论所有这些问题。

与某些Node模块(例如" npm"," fs"等)一样,Node JS"事件"模块也是基本Node JS平台的一部分。
我们无需执行任何操作即可设置Node JS Events模块。

为什么Node JS更快?与其他技术相比,Node JS应用程序由于此事件驱动的编程模型而提供了非常高的性能。

什么是EventEmitter?到目前为止,Node JS"事件"模块只有一个类可以处理事件:EventEmitter类。
它包含所有必需的功能,用于处理事件。

谁负责在Node JS应用程序中生成事件? EventEmitter类负责生成事件。
生成事件也称为发射。
这就是为什么此类名称为EventEmitter的原因,因为它在Node JS Platform中发出事件。

生成事件后,它将所有事件放入事件队列(请参阅" Node JS单线程事件循环体系结构"中有关事件队列用法的文章)。
然后,事件循环从事件队列中逐个拾取事件并进行相应处理。

谁负责处理Node JS Application中的事件? Node JS平台使用以下两个组件来处理事件。

  • EventEmitter类
  • Java脚本回调函数

EventEmitter类负责生成事件,而Java Script Callback函数负责处理事件。

我们可以用如下图来解释这个完整的过程:

  • 当Node JS应用程序开始或者结束操作时,EventEmitter类将生成事件并将其放入事件队列。

  • 事件队列维护事件队列。

  • 事件循环持续等待事件队列中的新事件。
    当它在事件队列中找到事件时,将其拉出并尝试对其进行处理。
    如果它们需要IO阻止操作或者长时间等待的任务,则分配相应的事件处理程序来处理它们。

  • 事件处理程序是JavaScript异步回调函数。
    他们负责处理事件并将结果返回到事件循环。

  • 事件循环将准备结果并将其发送回客户端。

开始Node JS Events编程的首要任务是导入"事件"模块,如下所示:

var events = require("events");

然后使用此事件变量并创建EventEmitter类的对象,如下所示:

var eventsEmitter = new events.EventEmitter();

EventEmitter的" emit()"函数

EventEmitter类具有" emit()"函数,该函数用于创建事件。
它需要一个参数。

eventsEmitter.emit(NameOfEventToCreate);

其中NameOfEventToCreate:我们需要将事件名称作为String传递给generate()函数调用以创建该事件。

例:

var events = require("events");
var eventsEmitter = new events.EventEmitter();
eventsEmitter.emit("mobileon");

EventEmitter的" on()"函数

EventEmitter类具有" on()"函数,该函数用于将事件与事件处理程序JavaScript函数绑定。
它有两个参数。

eventsEmitter.on(NameOfEventToBind, EventHandlerFuction);

其中NameOfEventToBind:我们需要将事件名称a作为字符串传递给on()函数调用,以将该事件绑定到给定的事件处理程序JavaScript函数。
和EventHandlerFuction:给定的事件处理程序JavaScript函数来处理该事件。
它可以是匿名JavaScript函数或者纯JavaScript函数。

示例:-本示例使用匿名JavaScript函数作为事件处理程序。

var events = require("events");
var eventsEmitter = new events.EventEmitter();
eventsEmitter.emit("mobileon",function(data){
        console.log(data);
});
eventsEmitter.emit("mobileon");

我们还可以将Plain JavaScript函数用作事件处理程序,如下所示:

var events = require("events");
var eventsEmitter = new events.EventEmitter();
eventsEmitter.emit("mobileon",mobileOnHadler);
eventsEmitter.emit("mobileon");

function mobileOnHadler(data){
  console.log(data);
}

有了有关EventEmitter类的知识,我们将开发一个实时的简单示例,以了解Node JS如何处理事件。

NodeJS事件示例:

此示例演示如何在Node JS Platform中读取文件形式FileSyste时引发事件。

  • 使用Enide 2014 Studio IDE创建Node JS项目
  • 从我之前的示例中复制或者创建package.json文件,并使用以下内容对其进行修改

package.json

{
"name": "events",
"version": "1.0.0",
"description": "events example",
"main": "events",
"author": "theitroad",
"engines":{
	"node":"*"
	}
}
  • 创建具有以下内容的文本文件" theitroad.txt"。
    我们将使用此文件来测试Node Js事件。

theitroad.txt

Dear, theitroad Readers. 
Thank You for your support.
  • 创建具有以下内容JavaScript文件

events.js

/**
 * theitroad  
 * Nodes Events Demo
 */
var events = require("events");
var fs = require('fs');
var eventsEmitter = new events.EventEmitter();

eventsEmitter.on('read',readFileContent);
eventsEmitter.on('display',displayFileContent);
eventsEmitter.on('finished',finished);
eventsEmitter.emit('read','theitroad.txt');

function readFileContent(fileName){
  console.log("Reading " + fileName + " file started:");
  fs.readFile(fileName, 'utf8', readFile);
}

function  displayFileContent(data){
  console.log("File Data:");
  console.log(data);
  eventsEmitter.emit('finished');
}

function finished(){
console.log("Reading and Printing File content job is done successfully.");
}

function readFile(err,data,fileName) {
  console.log("Reading " + fileName + " file done successfully.");
  eventsEmitter.emit('display',data);
}

代码扩展:

  • 在第5-6行,我们已将Node JS"事件"和" fs"(文件系统)模块导入到我们的应用程序缓存中。

  • 在第7行,我们创建了EventEmitter类的对象

  • 在第15-33行,我们编写了JavaScript函数。
    我们将它们用作事件处理程序函数。

  • 在第9行,我们使用EventEmitter类的on()方法将" read"事件与" readFileContent"事件处理函数绑定在一起。

  • 在第10行,我们使用EventEmitter类的on()方法将" display"事件与" displayFileContent"事件处理函数绑定在一起。

  • 在第11行,我们使用EventEmitter类的on()方法将"完成的"事件与"完成的"事件处理函数绑定在一起。

  • 在第12行,我们通过使用EventEmitter类的emit()方法传递文件名" theitroad.txt"作为输入来引发"读取"事件。

  • 最终项目的结构如下所示:

注意:-请忽略" events2.js"文件。
那是后备文件,供我将来参考。

  • 运行此JavaScript文件并观察Enide 2014 Studio IDE控制台的输出