Node.js回调函数以及事件循环使用介绍(基础介绍 三)

news2024/11/26 16:52:29

回调函数

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

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

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

例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。

回调函数一般作为函数的最后一个参数出现:

function foo1(name, age, callback) { }
function foo2(value, callback1, callback2) { }

阻塞代码实例

创建一个文件 input.txt ,内容如下:

百度以下,你就知道

创建 main.js 文件, 代码如下:

var fs = require("fs");

var data = fs.readFileSync('input.txt');

console.log(data.toString());
console.log("程序执行结束!");

以上代码执行结果如下:

$ node main.js
百度以下,你就知道

程序执行结束!

非阻塞代码实例

创建一个文件 input.txt ,内容如下:

百度以下,你就知道

创建 main.js 文件, 代码如下:

var fs = require("fs");

fs.readFile('input.txt', function (err, data) {
    if (err) return console.error(err);
    console.log(data.toString());
});

console.log("程序执行结束!");

以上代码执行结果如下:

$ node main.js
程序执行结束!
百度以下,你就知道

以上两个实例我们了解了阻塞与非阻塞调用的不同。第一个实例在文件读取完后才执行完程序。 第二个实例我们呢不需要等待文件读取完,这样就可以在读取文件时同时执行接下来的代码,大大提高了程序的性能。

因此,阻塞按是按顺序执行的,而非阻塞是不需要按顺序的,所以如果需要处理回调函数的参数,我们就需要写在回调函数内。

 事件循环

Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。

Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。

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

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


事件驱动程序

Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。

当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。

这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)

在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。

Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件,如下实例:

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

以下程序绑定事件处理程序:

// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);

我们可以通过程序触发事件:

// 触发事件
eventEmitter.emit('eventName');

实例

创建 main.js 文件,代码如下所示:

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

// 创建事件处理程序
var connectHandler = function connected() {
   console.log('连接成功。');
  
   // 触发 data_received 事件 
   eventEmitter.emit('data_received');
}

// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
 
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
   console.log('数据接收成功。');
});

// 触发 connection 事件 
eventEmitter.emit('connection');

console.log("程序执行完毕。");

接下来让我们执行以上代码:

$ node main.js
连接成功。
数据接收成功。
程序执行完毕。

Node 应用程序是如何工作的?

在 Node 应用程序中,执行异步操作的函数将回调函数作为最后一个参数, 回调函数接收错误对象作为第一个参数。

接下来让我们来重新看下前面的实例,创建一个 input.txt ,文件内容如下:

百度一下,你就知道

创建 main.js 文件,代码如下:

var fs = require("fs");

fs.readFile('input.txt', function (err, data) {
   if (err){
      console.log(err.stack);
      return;
   }
   console.log(data.toString());
});
console.log("程序执行完毕");

以上程序中 fs.readFile() 是异步函数用于读取文件。 如果在读取文件过程中发生错误,错误 err 对象就会输出错误信息。

如果没发生错误,readFile 跳过 err 对象的输出,文件内容就通过回调函数输出。

执行以上代码,执行结果如下:

程序执行完毕
百度以下,你就知道

接下来我们删除 input.txt 文件,执行结果如下所示:

程序执行完毕
Error: ENOENT, open 'input.txt'

因为文件 input.txt 不存在,所以输出了错误信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2235004.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux(CentOS)安装 MySQL

CentOS版本:CentOS 7 MySQL版本:MySQL Community Server 8.4.3 LTS 1、下载 MySQL 打开MySQL官网:https://www.mysql.com/ 直接下载网址:https://dev.mysql.com/downloads/mysql/ 其他版本 2、上传 MySQL 文件到 CentOS 使用F…

服务器被攻击排查记录

起因 我的深度学习的所有进程突然被killed,我以为是检修,后面发现好像简单的python代码可以正常运行。但是我的训练进程一启动就会被killed 第一时间没有用htop查看cpu,用top看着挺正常的,但是后面看htop,全是绿的&a…

TDengine 签约蘑菇物联,改造通用设备工业互联网平台

在当前工业互联网迅猛发展的背景下,企业面临着日益增长的数据处理需求和智能化转型的挑战。通用工业设备的高能耗问题愈发突出,尤其是由这些设备组成的公辅能源车间,亟需更高效的解决方案来提升设备运行效率,降低能源消耗。为此&a…

【大数据学习 | kafka高级部分】文件清除原理

2. 两种文件清除策略 kafka数据并不是为了做大量存储使用的,主要的功能是在流式计算中进行数据的流转,所以kafka中的数据并不做长期存储,默认存储时间为7天 那么问题来了,kafka中的数据是如何进行删除的呢? 在Kafka…

TOEIC 词汇专题:市场销售篇

TOEIC 词汇专题:市场销售篇 市场销售是企业推广产品和树立品牌形象的重要环节。今天为大家介绍在市场销售领域中常用的托业词汇,助力更好地理解相关英语场景。 1. 市场推广与活动 市场销售离不开推广活动,以下是一些核心词汇: A…

基于 Vue3、Vite 和 TypeScript 实现开发环境下解决跨域问题,实现前后端数据传递

引言 本文介绍如何在开发环境下解决 Vite 前端(端口 3000)和后端(端口 80)之间的跨域问题: 在开发环境中,前端使用的 Vite 端口与后端端口不一致,会产生跨域错误提示: Access to X…

OpenCV-Python-安装环境与测试样例

本文使用Pycharm安装openCV 1.打开pycharm终端 (GUI是我自己创建的项目名称) 错误:终端如果打开闪退的话 应对如下: 汉化版:文件->设置->工具->终端->红框位置设置cmd 英文版:file->settings->Tools->t…

Spark on YARN:Spark集群模式之Yarn模式的原理、搭建与实践

Spark 的介绍与搭建:从理论到实践-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交:本地与集群模式全解析-CSDN博客 目录 一、Spark on YARN 的优势 (一&#…

基于IM场景下的Wasm初探:提升Web应用性能|得物技术

一、何为Wasm ? Wasm,全称 WebAssembly,官网描述是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm被设计为一个可移植的目标,用于编译C/C/Rust等高级语言,支持在Web上部署客户端和服务器应用程序。 Wasm 的开发者参…

【JAVA毕业设计】基于Vue和SpringBoot的墙绘产品展示交易平台

本文项目编号 T 049 ,文末自助获取源码 \color{red}{T049,文末自助获取源码} T049,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

在全域数据整合过程中,如何确保数据的一致性和准确性

在全域数据整合过程中,确保数据的一致性和准确性是至关重要的,这不仅关系到数据分析结果的可靠性,还直接影响到企业决策的科学性和有效性。Aloudata AIR 逻辑数据编织平台通过数据虚拟化技术,为这一过程提供了强有力的支持。以下是…

w024基于SpringBoot的企业客户管理系统的设计与实现

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文件&#xff0…

element-plus快速实现table组件表头吸顶和滚动条吸底

使用devecoui 组件快速实现 element-plus table 组件,表头吸顶和滚动条吸底,且完美实现固定表头的吸顶效果,同时devecoui组件还可以实现,查询列表的快速开发,里面集成了更多的功能。详细功能请前往:添加链接…

C++STL容器详解——list

目录 一.list 1.list的介绍 2.为什么会有list? 二.list的常见接口 1.list的构造函数 2.list的遍历 3.迭代器类型 4.list的头插头删和尾插尾删 5.list任意位置的插入和删除 6.list的sort()及reverse() 7.迭代器失效 三.整体代码 一.list 1.list的介绍 list的文档说…

服务器数据恢复—EVA存储故障导致上层应用不可用的数据恢复案例

服务器存储数据恢复环境: 一台EVA某型号控制器EVA扩展柜FC磁盘。 服务器存储故障&检测: 磁盘故障导致该EVA存储中LUN不可用,导致上层应用无法正常使用。 服务器存储数据恢复过程: 1、将所有磁盘做好标记后从扩展柜中取出。硬…

hf_transformers

强者自定义,弱者用默认,傻逼不看说明书 1. 2.在 model.generate()里填参数,默认为20个新token generated_ids model.generate(**model_inputs, max_new_tokens50) 3. 默认情况下,除非在GenerationConfig文件中指定&#xff0…

Sigrity Power SI 3D-EM Inductance Extraction模式如何进行电感的提取操作指导(一)

Sigrity Power SI 3D-EM Inductance Extraction模式如何进行电感的提取操作指导(一) Sigrity Power SI使用3D-EM Inductance Extraction模式可以进行电感的提取,以下图为例 2D 视图 <

学习记录:js算法(八十七):单词搜索

文章目录 单词搜索思路一思路二 单词搜索 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其…

应急救援无人车:用科技守护安全!

一、核心功能 快速进入危险区域&#xff1a; 救援无人车能够迅速进入地震、火灾、洪水等自然灾害或重大事故的现场&#xff0c;这些区域往往对人类救援人员构成极大威胁。 通过自主导航和环境感知技术&#xff0c;无人车能够避开危险区域&#xff0c;确保自身安全的同时&…

辩论赛——动态IP与静态IP的巅峰对决

尊敬的各位观众&#xff1a; 大家好&#xff01;欢迎来到今天的演说舞台&#xff0c;我是主持人小蝌蚪。今天&#xff0c;我们将见证一场精彩绝伦的辩论&#xff0c;辩论的双方是动态IP和静态IP。他们将围绕各自的优缺点展开激烈的辩论&#xff0c;为我们揭示代理IP世界中的奥…