nodejs笔记之:事件驱动,线程池,非阻塞,异常处理等

NodeJS中的事件驱动程序实现原理解析 前言 Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。 当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。 这个模型非常高效可扩展性非常强,因为 webserver 一直接受请求而不等待任何读写操作。(这也称之为非阻塞式IO或者事件驱动IO) 在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。 整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Su 阅读详情

事件驱动:

事件驱动的模型:


这里写图片描述

事件驱动的原理:

原理总结:

Nodejs 会把所有请求和异步操作都放到一个事件队列中,用户的每一个请求就是一个事件。主线程先把普通代码执行完毕,然后会循环事件队列里的函数,如果遇到有IO的操作,nodejs会去线程池里拿出一个线程去执行IO的操作,执行完毕后再把拿到数据的回调函数,放到事件队列的尾部,继续事件循环。

线程池

线程池的概念:

Node是单线程的,这里的单线程仅仅是javascript执行在单线程中,V8引擎不支持io操作,在node中,无论是类unix还是windows平台内部完成IO的操作都有线程池。

在windows下,node实现IO异步的解决方案是iocp:调用异步方法,等待IO完成之后的通知,执行回调,用户无需考虑轮询,但是其内部仍然是线程池原理,不同之处在于这些线程池是由系统内核接受管理。
在linux下,0.9.3版本之前的node是使用libeio配合libuv实现的异步IO,在此版本之后的node自行实现了线程池来完成异步io操作。
本质上nodejs 是个多线程平台。如果有io操作,nodejs交给 中间层libuv去做,它的底层就是C或者C++来实现的,所以nodejs本质上还是个多线程平台。

IO 操作

io操作就是以流的形式,进行的操作,比如网络请求,文件读取写入。io操作也就是input和output的操作。

阻塞IO

在调用阻塞io时,应用程序需要等待io完成才能返回结果。
阻塞io的特点:调用之后一定要等到系统内核层面完成所有操作之后,调用才结束。
阻塞io造成CUP等待IO,浪费等待时间,CPU的处理能力不能得到充分利用。

非阻塞IO

为了提高性能,内核提供了非阻塞io,非阻塞io跟阻塞io的差别是调用之后会立即返回。
阻塞io完成整个获取数据的过程,而非阻塞io则不带数据直接返回,要获取数据,还要通过问价你描述符再次读取。
非阻塞io返回之后,cpu时间片可以用来处理其他事物,此时性能提升非常明显。

Nodejs中的异常处理

Node是单线程运行环境,一旦抛出异常,没有被处理,就会引起整个进程崩溃。
Node的异常处理,对于保证系统稳定运行非常重要。
Node有三种方式,处理一个错误 :
    1. throw 抛出异常。
    2. 将错误对象传递给回调函数,由回调函数负责处理错误。
    3. 使用try catch捕获异常有时候会不及时,合理的放置 trycath 去捕获,在异步内部,而不是在异步的外层去捕获,就像是下面的在回调函数内部去try catch 。

回调函数

Node采用: 将错误对象作为第一个参数传入回调函数,这样就避免了捕获错误与发生错误不在一个时间段上的问题。

回调函数的设计

对于一个函数需要定义回调函数,node统一规定:

  1. 回调函数一定作为参数的最后一个参数出现:

    Function foo(arg1,arg2,callback){}
  2. 回调函数的第一个参数默认接收错误对象,第二个参数才是真正的回调函数(便于外界获取调用的错误情况)

    // 执行一个doRead() 函数,假设有这么一个函数,主要看里面的异常处理
    doRead(obj,function(err,res){
        if(err) throw err; // err 是错误对象
        console.log(res); // res 是具体的结果或者数据
     } )
  3. 强调错误优先

    • 错误优先的回调函数,第一个参数是上一步的错误对象
    • 通过判断回调函数中的err是否为null,来检测异步操作过程是否出现错误,我们用下面的例子来举例说明:

      const fs = require('fs');
      // 定义一个读文件函数
      function readFile(path, callback) {
        fs.readFile(path, 'utf8', function (err, data) {
          if (err) {
            return callback(err, null);
          }
          callback(null, '输出的数据为:' + data);
        });
      }
      
      readFile('./data/index.html', function (err, data) {
        if (err) {
          throw err;
        }
        console.log(data);
      });
      

总结:

  1. Node规定,如果某个函数需要作为参数,则回调函数是最后一个参数,另外,回调函数本身的第一个参数,约定为上一步传入的错误对象
  2. 传统的错误捕捉机制try catch,尽量不要使用,在异步操作中容易出错。
  3. 一旦异步操作发生错误,就把错误对象传递到回调函数,如果没有发生错误,回调函数的第一个参数就是null,如果不是null,就肯定出错了。
Nodejs 工作线程 Node.js 中的工作线程模块允许我们并行运行 JavaScript 代码,防止 CPU 密集型操作阻塞应用程序的主线程。在深入研究本模块之前,了解一些关键概念非常重要。熟悉这些概念将有助于我们有效地使用工作线程并从中受益。 阅读详情

相关推荐

面试题整理|50个NodeJS面试题

面试整理|50个NodeJS面试题初级NodeJS面试题中级NodeJS面试题高级NodeJS面试题《Nodejs仿微博网站》 Node.js是一种服务器端脚本工具,使用它可以轻松构建从简单的命令行程序到复杂的企业级 Web 应用程序的所有内容。 本篇文章,将为大家分享50个和NodeJS相关的面试题及其解析,难度分为:初级、中级、高级三个部分,由易到难,循序渐进。 初级NodeJS面试题 Q1、如何区分 JavaScript 和 Node.js? 特征 JavaScript NodeJS

pengxian00007的博客 9609

Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33781606的博客 549

快速,高效的Node.js Worker线程池实现-Node.js开发

快速,高效的Node.js工作线程池实现piscina-node.js工作池:check_mark:线程之间的快速通信:check_mark:涵盖固定任务和可变任务方案:check_mark:支持灵活的池大小:check_mark:适当的异步跟踪集成:check_mark:跟踪运行统计信息和等待时间:check_mark:取消支持:check_mark:支持强制执行内存资源限制:check_mark:支持CommonJS,ESM和TypeScript:check_mark:自定义任务队列:check_mark:在TypeScript中编写Linux上的可选CPU调度优先级。 适用于Node.js 12.x及更高版本。 麻省理工学院

Node.js 进程与线程:上篇

Node.js 进程与线程:上篇

小楠的博客 1072

理解 Node.js 事件驱动机制的原理

学习 Node.js 一定要理解的内容之一,文中主要涉及到了 EventEmitter 的使用和一些异步情况的处理,比较偏基础,值得一读。 大多数 Node.js 对象都依赖了 EventEmitter 模块来监听和响应事件,比如我们常用的 HTTP requests, responses, 以及 streams。 const EventEmitter = require('events'); 事件驱动机制的最简单形式,是在 Node.js 中十分流行的回调函数,例如 fs.readFile。 在回调函数这种形式中,事件每被触发一次,回调就会被触发一次。 我们先来探索下这个最基本的方式。

RustFS vs MinIO:深入对比分布式存储的性能、功能与选型指南

RustFS与MinIO是两款热门分布式存储系统,分别针对高性能与通用场景设计。RustFS基于Rust语言,在吞吐量(最高提升46%)、延迟(降低37%)和资源效率(内存占用减少67%)上显著优于MinIO,适合AI训练、金融级应用等高性能需求。MinIO凭借成熟的S3兼容性、云原生集成和企业级功能,更适用于混合云及现有S3生态。许可方面,RustFS采用Apache 2.0,MinIO为AGPLv3。选型建议:优先RustFS应对性能敏感场景,选择MinIO注重生态兼容性,也可考虑混合架构策略。

分布式存储与RustFS的博客 2024

NodeJs事件驱动和非阻塞机制详解

NodeJs事件驱动和非阻塞机制详解 NodeJs强调错误优先 因为事件的操作大多数都是异步的方式,无法通过try catch捕获异常 采用错误优先的回调函数 NodeJs基本介绍(菜鸟教程) Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。 Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。 Nod...

CaseyWei 1万+

若依ruoyi框架实现单点登录或者接入统一认证

log.info("单点登录用户[{}]不存在, 需要创建.", loginName);log.info("单点登录用户[{}]已存在.", loginName);jsonObjectData.put("nickName","单点1");if (code.equals("0")) {//验证成功需要自动登录。jsonObject.put("msg","验证成功");ajax.put("msg", "登录成功");

GitHub质检员 2万+

nodejs笔记——非阻塞、事件驱动

var fs = require('fs') function fn(){ fs.readFile('nodejs.js', (err, data) => { console.log(data.toString()) //这里返回的data值是属于回调函数,不属于外面的fn函数,因此从外面拿不到这里的data值 return data }) //因为阻塞的原因无法将data值返回出去 return data } console.log(fn()) 上段代码中,无法获取到da

weixin_43340295的博客 277

Unity接入Google登录:Credential Manager完整集成指南与避坑实践

在移动应用开发中,第三方登录是提升用户体验和降低注册门槛的关键技术。其核心原理是通过OAuth 2.0等授权协议,安全地获取用户在平台的身份凭证。对于面向海外市场的Unity应用,Google登录因其庞大的用户基数成为首选方案。然而,随着Android系统更新和隐私政策收紧,传统的WebView登录方式面临兼容性挑战。Credential Manager作为Google推出的现代化凭据管理API,通过系统级集成解决了这一问题,它统一了密码、通行密钥和第三方登录的调用接口,显著提升了登录成功率和原生体验。在U

weixin_28025327的博客 321

5.2 自抗扰控制 (ADRC)

自抗扰控制(Active Disturbance Rejection Control, ADRC)是由韩京清研究员于1998年提出的一种不依赖被控对象精确数学模型的新型控制技术[reference:0]。其核心思想是将系统的模型不确定性、内部参数摄动以及外部负载变化等所有影响统一定义为“总扰动”,通过一个名为扩张状态观测器(ESO)的环节对其进行实时估计并主动补偿,从而实现动态解耦和强鲁棒性。

技术工作者 1178

Nodejs优缺点,使用场景

一. NodeJS的特点 我们先来看看NodeJS官网上的介绍: Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O mode...

千年似流水的博客 1万+

保姆级教程:在华为云Ubuntu服务器上快速搭建RAGflow开发环境(避坑指南)

本文提供了一份在华为云Ubuntu服务器上快速搭建RAGflow开发环境的保姆级教程。针对网络拉取镜像等常见问题,详细介绍了从服务器选型、系统优化、Docker配置到RAGflow部署与验证的全流程,并给出生产环境调优建议,帮助开发者高效避坑,快速构建企业级应用环境。

weixin_29250403的博客 87

Nodejs 的非阻塞 I O、异步、事件驱动

1、 Nodejs 的单线程 非阻塞 I/O 事件驱动 在 Java、PHP 或者.net 等服务器端语言中,会为每一个客户端连接创建一个新的线程。 而每个线程需要耗费大约 2MB 内存。也就是说,理论上,一个 8GB 内存的服务器可以同时 连接的最大用户数为 4000 个左右。 要让 Web 应用程序支持更多的用户,就需要增加服务器 的数量,而 Web 应用程序的硬件成本当然就上升了。 Node.js 不为每个客户连接创建一个新的线程,而仅仅使用一个线程。 当有用户连接了, 就触发一个内部事件,通过非阻塞

郑怪兽 1167

一分钟理解 “熔断“, “限流“ 与 “降级“

熔断,本质是一种“故障隔离”机制,用于当某个依赖服务出现持续故障(如响应超时、错误率飙升)时,暂时切断对该服务的调用,避免故障扩散到整个系统,防止“雪崩效应”;待依赖服务恢复正常后,再逐步恢复调用。其核心逻辑参考了现实中的“电路保险丝”——电路过载时,保险丝熔断,切断电路,保护电器不被烧毁;故障排除后,更换保险丝,电路恢复正常。闭合状态(Closed):正常状态,请求可以正常调用依赖服务,同时监控调用的错误率、超时率等指标。打开状态(Open)

h a 6 6 6 c k 为 你解决复杂难题! 1487

【Matlab】飞行器气动弹性仿真与分析

气动弹性是飞行器设计领域的核心交叉学科,融合了空气动力学、结构动力学和控制理论,主要研究飞行器结构在气动力作用下的弹性变形、振动响应及相互耦合规律,直接影响飞行器的飞行稳定性、操纵性和结构安全性。随着飞行器向高速度、高机动性、轻量化方向发展,气动弹性问题愈发突出,如颤振、发散、嗡鸣等现象,严重时会导致飞行器结构破坏甚至飞行事故,因此气动弹性仿真与分析已成为飞行器设计、验证和优化的关键环节。当前,飞行器气动弹性仿真面临诸多技术挑战:气动力与结构变形的强耦合特性难以精准描述,易出现仿真误差;

unber的博客 238

Nodejs笔记 Nodejs非阻塞IO、异步及事件驱动EventEmitter解决异步

一、非阻塞 1.1 非阻塞 var fs = require('fs'); // 非阻塞 console.log('1'); fs.readFile('mime.json', function(err, data) { // console.log( data ); console.log('2'); }) console.log('3'); 1.2 非异步 function getMime() { return 123; } console.log( getMime() )

林飞的梦呓 1044

GitHub霸榜神器!NextChat领衔DeepSeek全栈开发范式

NextChat(原ChatGPT-Next-Web)是GitHub上斩获81.2K星标的现象级开源项目,定位为"轻量级AI助手终端",支持DeepSeek、Claude、GPT-4、Gemini等20+主流大模型。• 原生集成DeepSeek、GPT-4、Gemini Pro等模型API,同时兼容RWKV-Runner、LocalAI等自建模型框架,通过环境变量。• 客户端体积仅5MB(Windows安装包约6MB),采用PWA渐进式Web应用技术,首屏加载速度优化至100KB级,老旧设备亦可流畅运行。

实战AI智能体 900

NodeJs 异步非阻塞

一般来说,高并发的解决方案就是提供多线程模型,服务器为每个客户端请求分配一个线程,使用同步 I/O,系统通过线程切换来弥补同步 I/O 调用的时间开销。比如 Apache 就是这种策略,由于 I/O 一般都是耗时操作,因此这种策略很难实现高性能,但非常简单,可以实现复杂的交互逻辑。 而事实上,大多数网站的服务器端都不会做太多的计算,它们接收到请求以后,把请求交给其它服务来处理(比如读取数据库),...

Nodejs 1447

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Nodejs 中的非阻塞I/O、异步和事件驱动

Node.js使用 事件驱动机制、具有非阻塞的I/O模型这样的特点,Node.js中的大多数Api都用到了异步函数,那麽又该如何获取异步函数返回的数据呐?

渣渣砖 933

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

04. nodejs的异步、回调、非阻塞IO、事件驱动

04 nodejs的异步、回调、非阻塞IO、事件驱动 ​ nodejs具有单线程、非阻塞io、事件驱动的特性,非阻塞io和单线程联系在一起,异步非阻塞的特性适合高并发场景,并且优于java和php等传统后台语言。具体请看前一篇文章的理解和分析: 异步程序的写法 回调函数 nodejs的异步提供了强大的并发处理能力,但是在写程序时需要注意,他的语法并不是像java和php一样是从上到下执行的,具体...

凉 987

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

nodejs笔记

NodeJS实现高并发的原理 1.Nodejs的诞生 为了解决web服务器的高并发性能问题 2.单线程的好处 业务1的计算1刚调用完,在调用I/O请求时马上调用业务2的计算1,CPU的利用率永远百分百,不在创建销毁线程,缺点:一个用户线程崩溃,其他人整个服务崩溃 3.非阻塞I/O机制 传统的单线程,I/O阻塞代码执行,但nodejs使用非阻塞I/O使得线程永远在执行计算操作,cpu利用率永远是100% 4.事件驱动模型 应用层:即node.js的模块,如fs,http等 v8引擎层: 解析JavaScr

weixin_42929948的博客 423

NodeJS(一)通俗理解 NodeJS

文章目录前言一、nodeJS是什么?二、nodeJS之前的主流是什么?三、为什么要用nodeJS?总结 前言 nodeJS 一、nodeJS是什么? Node.js 是一个基于 V8 JavaScript 引擎构建的 JavaScript 运行时(runtime)。 官网:http://nodejs.cn/ 也可以理解为用JavaScript写的服务端平台,能运行在服务端的框架。 二、nodeJS之前的主流是什么? NodeJS是近年来比较火的,这一方面得益于其在后端处理高并发的卓越性能,另一方面在no

CathyleeQ的博客 1万+

Nodejs之事件驱动+非阻塞io模型

1什么是i/o? io input、output 输入输出,电脑的输入输出,例如音频录音表示声音输入、听音乐是声音的输出 网络上的传输全部是在传字符串,i/o在服务器上可以理解为读写操作。2什么是并发? 一个时间段中有几个程序都处于已启动运行到运行完毕之间。3异步i/o与事件驱动3.1什么是进程?进程是为运行当中的应用程序提供运行环境的 一个运行当中的应用程序就会有一个进程与之相对应3

xiaowei的博客 6772

Nodejs 的非阻塞I/O、异步、事件驱动 回调处理异步 events模块处理异步

1、Nodejs的单线程非阻塞I/O事件驱动 在Java、PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而Web应用程序的硬件成本当然就上升了。Node.js不为每个客户连接创建一个新的线程,而仅...

weixin_43496606的博客 3万+
上一篇: 在优快云的安卓版本的App中找到了的一个BUG
下一篇: JavaScript中的模块化之AMD和CMD
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值