NodeJS事件模块和EventEmitter
我们已经在以前的文章中讨论过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控制台的输出