使用events.EventEmitter 控制Node.js 程序执行流程

标题写的可能也不太对,大家领会精神;

Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。

Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

Node.js 异步编程的直接体现就是回调。

异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。

回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。

例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。

这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。

Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。

Node.js 几乎每一个 API 都是支持回调函数的。

Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。

Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数。

大意就是说:与大多数 代码从上至下线性执行的 程序不同,Node.js 程序不会“等”,

当程序执行到需要I/O执行时间的回调函数时,会主动略过等待,继续执行下面的代码;

因此就会出现一种弊端:一个特定函数的输入(参数),是数个回调函数的返回;

程序的执行机制会略过 对回调函数的等待,直接执行下面的特定函数;此时特定函数并没有等到回调函数返回的输入;

例子如下:

var fs = require("fs");
var array = [1, 2, 3, 4, 5];
var json = {};
for (let index = 0; index < array.length; index++) {
    const element = array[index];
    deal(element, function (ret) {
        json[element] = ret;
        console.log(json);
    });
}

console.log(json);

function deal(num, callback) {
    fs.readFile(num + ‘.txt‘, function (err, data) {
        if (err) {
            console.error(err);
            callback(err);
        } else {
            callback(data.toString().trim());
        }
    });
}

Object {}
Object {1: "11111"}
Object {1: "11111", 5: "55555"}
Object {1: "11111", 3: "33333", 5: "55555"}
Object {1: "11111", 3: "33333", 4: "44444", 5: "55555"}
Object {1: "11111", 2: "22222", 3: "33333", 4: "44444", 5: "55555"}

回调函数要以数组里的内容作为文件名,读取文件中的数据作为返回值;

但程序不会等待文件读取完成,在没有一个文件读取完毕的情况下就执行了打印操作,输出了空对象;

如果想要按顺序线性执行文件读取,在读取完毕后打印输出,不仅浪费时间,而且一层套一层代码冗余,

还无法预估数组大小(回调函数个数)。

Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。

解决的办法是:Node.js 的事件驱动特性,让打印作为一个事件,在所有的回调函数执行完后,再触发打印操作;

var fs = require("fs");
var events = require(‘events‘);
var emitter = new events.EventEmitter(); 

var array = [1, 2, 3, 4, 5];
var count = 0;
var json = {};

for (let index = 0; index < array.length; index++) {
    const element = array[index];
    deal(element, function (ret) {
        json[element] = ret;
        console.log(json);
    });
}

emitter.on(‘dataBack‘, function() {
    count ++;
    if(count == array.length){
        console.log(json);
    }
}); 

function deal(num, callback) {
    fs.readFile(num + ‘.txt‘, function (err, data) {
        if (err) {
            console.error(err);
            callback(err);
            emitter.emit(‘dataBack‘);
        } else {
            callback(data.toString().trim());
            emitter.emit(‘dataBack‘);
        }
    });
}

Object {1: "11111"}
Object {1: "11111", 4: "44444"}
Object {1: "11111", 3: "33333", 4: "44444"}
Object {1: "11111", 3: "33333", 4: "44444", 5: "55555"}
Object {1: "11111", 2: "22222", 3: "33333", 4: "44444", 5: "55555"}
Object {1: "11111", 2: "22222", 3: "33333", 4: "44444", 5: "55555"}

在程序中添加打印事件和事件触发,全部数据都集齐后再打印,

虽然还有count的锁不锁的问题存在,但实际的问题已然解决;

嗯嗯。

引用和改写的程序都来源于 Node.js 教程 | 菜鸟教程

Node.js 文件系统 | 菜鸟教程

Node.js EventEmitter | 菜鸟教程

J.X.Duasonir

原文地址:https://www.cnblogs.com/duasonir/p/9186410.html

时间: 2024-10-11 10:59:00

使用events.EventEmitter 控制Node.js 程序执行流程的相关文章

node js 异步执行流程控制模块Async介绍

1.Async介绍 sync是一个流程控制工具包,提供了直接而强大的异步功能.基于Javascript为Node.js设计,同时也可以直接在浏览器中使用. Async提供了大约20个函数,包括常用的 map, reduce, filter, forEach 等,异步流程控制模式包括,串行(series),并行(parallel),瀑布(waterfall)等. 项目地址:https://github.com/caolan/async 2. Async安装 npm install async 3.

node.js教程基础:第一个node.js程序

第一个Node.js程序 可以是基于控制台console和基于Web的node.js应用程序. 基于console的node.js例子 文件:console_example1.js 1 console.log('Hello World); 打开Node.js命令提示符并运行以下代码: >node console_example1.js >Hello World 在这里,console.log()函数在控制台上显示消息. 我们还可以在console.log()函数中使用格式说明符: 1 cons

在Visual Studio上开发Node.js程序

[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio(NTVS),虽然现在仅发布了1.0 Alpha版本,但使用起来已经非常方便.而且,其开发团队与Python Tools for Visual Studio(PTVS)是同一个,而PTVS就是Visual Studio 2013中要创建自带的Python项目需要安装的那个程序,所以大可放心的使用NT

如何使用npm发布Node.JS程序包

如何使用npm发布Node.JS程序包 Heero.Luo发表于3年前,已被查看5065次 npm是Node.JS的程序包管理器.进行Node.JS开发时,经常使用它安装/卸载程序包.实际上,发布程序包的工作也是由它来完成的. 配置package.json 要打包程序,首先要配好各项设置,这些设置都由程序包根目录下的package.json指定.package.json的内容必须是严格的JSON格式,也就是说: 字符串要用双引号括起来,而不能用单引号: 属性名一定要加双引号: 最后一个属性后千万

一种简单的生产环境部署Node.js程序方法

最近在部署Node.js程序时,写了段简单的脚本,发觉还挺简单的,忍不住想与大家分享. 配置文件 首先,本地测试环境和生产环境的数据库连接这些配置信息是不一样的,需要将其分开为两个文件存储 到config目录下,比如: 开发环境配置文件config/development.js: module.exports = { port: 3001, mysql: { user: 'root' } }; 生产环境配置文件config/production.js: module.exports = { po

在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure

[题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在其他机器上运行程序,进而需要远程调试功能,不过还好,NTVS提供的远程调试也非常方便. [系列索引] 在Visual Studio上开发Node.js程序——NTVS介绍及使用 在Visual Studio上开发Node.js程序(2)——NTVS远程调试及发布到Azure [文章索引] NTVS远

在Visual Studio 2013 上开发Node.js程序

[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio(NTVS),虽然现在仅发布了1.0 Alpha版本,但使用起来已经非常方便.而且,其开发团队与Python Tools for Visual Studio(PTVS)是同一个,而PTVS就是Visual Studio 2013中要创建自带的Python项目需要安装的那个程序,所以大可放心的使用NT

程序执行流程(粗略)

程序执行流程(粗略) 用户发出请求 前台进行js规则验证(良好的用户体验) 按照一定的规则进行数据提交 (数据没有封装的提交 和 数据封装过后的提交) 控制层进行数据的接收 1.进行数据的非空.规则验证 || 规则验证可以读取配置文件 2.处理session信息 3.进行权限的验证 || 可以使用权限拦截器或过滤器 # 分清数据来源::: 来源于用户输入(输入数据 ), 来源于系统生成(当前时间) , 默认值在业务层之中设置保证业务的可移植性 # 在调用业务之前一定要保证将业务需要的信息已经进行

&lt;01&gt;主函数分析+创建一个新的Target+C语言程序执行流程

1.C语言的源程序的后缀:.c格式 2.C语言源程序: 1)由函数构成 2)在一个程序中,只有一个主函数(主函数由系统调用) 3)函数只有被调用的时候,才执行 4)如果没有主函数程序无法运行 5) C语言中语句结束一定要有分号 3.主函数的写法: int main(){ printf("hello world"); return 0; } 4.C语言程序的执行 1)command+r 2)点击左上角的 三角 符号 //Program ended with exit code: 0  程