分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

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

发布时间:2023-09-06 02:00责任编辑:彭小芳关键词:jsNode

使用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

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

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

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved