node.js的事件机制
发布时间 - 2026-01-10 22:55:55 点击率:次首先, 补充下对node 的理解:

nodeJs 是一个单进程单线程应用程序, 但是通过事件和回调支持并发, 所以性能非常高~
那么什么是单进程单线程呢~(写给语文跟我一样不好的小伙伴)
我们来看下单进程和多进程的区别:
1. 多进程的优势在于任务的独立性,比如某个任务单独作为一个进程的话,崩溃只影响自己的服务,其他任务不受影响.如果是多个任务在同一个进程内部利用多个线程进行处理,某个线程发生了未处理的异常的话,会导致整个进程完蛋,所有的任务跟着遭殃
2. 从资源分配上来说,多进程方案比多线程方案更加灵活和自由
3. 不过任务间的通信方面多进程要比多线程复杂些,编一个好的多进程通信方案要比多线程间的通信方案困难多了(小伙伴们注意区分进程和线程哟~)
以web server为例的话,比如我的服务器上架设了三个网站,如果是用一个进程管理的话, 网站A遭受攻击死掉了,意味着另外两个网站会出现同样的现象. 如果是分开独立的进程的话,三个网站互不影响
具体来分呢, 单进程对比多进程有什么优点呢:
1) 初期实现起来比较简单快速, 而且不用考虑进程间通信的工作量
2) 单一性使得部署和运营比较简单(这还用说 / 白眼ing)
3) 内存占用少, 不过呢, 现在内存很廉价, 但是一分钱也是钱呀!
4) 进程内部通信效率比IPC/scoket(多进程数据通讯的终端)等要高效, 我一嗓子你就听见了, 就不用费力气装个电话了
当然, 肯定优缺点!不然花那么多钱开多进程的人也太蠢了 ~
单进程对比多进程的缺点~
1) 中后期随着业务逻辑的复杂化和需求的增加,这个单进程会变得臃肿, 难以维护。 一个任务分解成多个进程会使单个进程的逻辑简单,而不容易出错
2) 同进程内模块间是强依赖关系,需要在一起编译相互的影响也比较大。 这相对于多进程间通信来说, 耦合度较大(不符合高内聚低耦合的伟大思想), 不利于多团队并行开发。 多进程更便于多语言的协作开发。
3)任何模块的崩溃都将导致整个进程的失效,多进程模式更加稳定健壮,业务处理程序隔离运行, 一个go home不会影响其他(你敢崩我也崩);
4) 性能问题: 如果不支持进程间数据通讯的话,单进程的容量是受限的, 这个性能瓶颈对于支持群组类服务的尤其需要考虑。多进程部署极其灵活,可以扩充机器数量来提高系统处理性能,还可以从硬件上避免单点故障。(一个人承受不来)
5) 单进程中多线程难调试( 一枪开出去, 一群人倒了, 我还得检查一下谁中枪了才能给你debug)
举个小栗子
你有一个对象, 对象特别挑食, 但是对象只喜欢一种菜, 你每天做给她吃。
这就是个单进程单线程的模型, 如果你做的不好吃了, 对象不吃了。
但是我有一个对象, 她喜欢吃10种菜, 我每天端过去10份, 哪天其中某一份醋放多了, 对象说真难吃, 今天不吃了。这就是单进程多线程的模型。一个菜不好吃导致对象不吃了(全部线程崩掉)
.. 如果我有两个对象.. 每个对象喜欢吃一种菜
ok, 一个对象觉得好吃, 吃的脸圆圆的三下巴, 一个觉得不好吃常年不吃, 骨瘦如柴。
这就是多进程单线程互不影响的模型.. 多进程多线程我就不举栗了 ~
说到这里, 小伙伴有没有对单进程单线程有一些理解呢。nodeJs 就是单进程单线程的应用程序, 进程间互不影响, 绑定多个事件可以同时触发~ 不用等你完了我再有动作, 所以nodeJs性能很高。
nodeJs 单线程类似进入一个while(true ) 的事件循环, 知道没有事件观察者的时候退出(每绑定一个事件, 就生成一个事件观察者), 当有事件发生的时候, 就会调用该事件的回调函数。
事件驱动程序
nodeJs 使用事件驱动模型(稍后说), 当web server 接收到请求时, 就把它关闭然后进行处理, 然后去服务下一个web 请求。可以理解成我触发事件, 就先关闭这个事件驱动, 然后处理, 我觉得是在防止二次触发~ 造成不正确的负载和意料之外的结果,这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)
可能有的小伙伴会问了, 什么是 事件驱动模型呢~
其实在了解事件驱动之前, 我们可以先看一下事件驱动的三大要素:
1) 事件源: 谁来接受外部事件
2) 侦听器: 能够接收事件源通知的对象
3) 事件处理程序: 用于处理事件
好, 包含以上三点的就是一个完整的事件驱动程序。
举个栗子
如果有一天你走在路上一不小心被天上掉下来的花瓶砸到了,并且晕死了过去。那么整个过程其实就是一个事件处理流程,而且我们可以非常方便的分析出刚才所提到的事件驱动模型中的三大要素。
1.被砸晕的这个人其实就是事件源,因为他是能够接受到外部的事件的源体。
2.侦听器就是这个人的大脑神经,因为它会感知到疼痛。
3.事件处理就是这个人晕死了过去。
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。
说了那么多, 事件绑定怎么写呢。
在node 里, 有个事件模块 events, 我们可以通过实例化的events 对象 来绑定事件。
上代码:
var event = require('events'); // 引入事件模块
var eventObj = new event(); // 实例化一个事件对象
eventObj.on('起床', function() { // 绑定事件和事件回调
console.log('洗脸刷牙');
});
eventObj.emit('起床'); // 触发事件的方法
结果是符合预期的。
但是有一点需要注意哦, 当你想移除事件的时候, 直接eventObj.removeListener(‘起床')
然后各种报错~
其实正确的移除事件的方法是这样的~
上代码:
var event = require('events'); // 引入事件模块
var eventObj = new event(); // 实例化一个事件对象
function getUp() {
console.log('洗脸刷牙');
}
eventObj.on('起床', getUp);
eventObj.emit('起床');
eventObj.removeListener('起床', getUp);
eventObj.emit('起床');
成功移除事件~
node 还提供了只触发单次事件的方法~
eventObj.once(‘起床', getUp)
还有移除全部事件呀~
eventObj.removeAllListeners(getUp), 像我这样指定了getUp的事件, 则移除所有触发该事件的监听器。
eventObj.setMaxListeners(n) 参数是一个数字, 因为node默认了绑定事件最多10个, 10个以上的时候会警告。 如果不想被警告就设置最大监听器个数咯~
eventObj.listeners(even) 返回指定事件的监听器数组
eventObj.emit(getUp, [arg1], [arg2], [...])
按照参数的顺序执行事件, 返回值是true或者false。有此监听事件就返回true。
不知道小伙伴们有没有疑惑, 我明明已经把events 模块加载过来了, 为什么还要实例化才能用呢~
大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。
为什么要这样做呢?原因有两点:
首先,具有某个实体功能的对象实现事件符合语义(可以自己命名了啊喂(#`O′) ), 事件的监听和发射都应该是一个对象的方法。
其次 JavaScript 的对象机制是基于原型的, 支持部分多重继承,继承 EventEmitter不会打乱对象原有的继承关系。
Node 应用程序是如何工作的?
在 Node 应用程序中,执行异步操作的函数将回调函数作为最后一个参数, 回调函数接收错误对象作为第一个参数。
接下来让我们来重新看下前面的实例,创建一个 input.txt ,文件内容如下:
123456123123
创建 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 对象的输出,文件内容就通过回调函数输出。
执行以上代码,执行结果如下:
123456123123
接下来我们删除 input.txt 文件,执行结果如下所示:
程序执行完毕Error: ENOENT, open 'input.txt'
因为文件 input.txt 不存在,所以输出了错误信息。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# node.js
# 事件机制
# 谈一谈JS消息机制和事件机制的理解
# ExtJs事件机制基本代码模型和流程解析
# 利用Javascript实现一套自定义事件机制
# 深入解析JavaScript框架Backbone.js中的事件机制
# 详解Node.js中的事件机制
# JavaScript的事件机制详解
# 深入理解JS DOM事件机制
# 深入理解Vue.js源码之事件机制
# javaScript事件机制兼容【详细整理】
# 浅析JavaScript中的事件机制
# JS内部事件机制之单线程原理
# JS 事件机制完整示例分析
# 回调
# 单线程
# 绑定
# 多线程
# 多个
# 吃了
# 移除
# 我们可以
# 应用程序
# 是一个
# 就会
# 就不
# 这就是
# 三大
# 而不
# 要比
# 单点
# 错误信息
# 喜欢吃
# 晕死
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
EditPlus中的正则表达式实战(5)
如何用西部建站助手快速创建专业网站?
Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
如何获取PHP WAP自助建站系统源码?
Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境
音响网站制作视频教程,隆霸音响官方网站?
Laravel如何使用Passport实现OAuth2?(完整配置步骤)
如何快速查询网址的建站时间与历史轨迹?
敲碗10年!Mac系列传将迎来「触控与联网」双革新
Laravel如何使用.env文件管理环境变量?(最佳实践)
如何快速上传建站程序避免常见错误?
重庆市网站制作公司,重庆招聘网站哪个好?
Android利用动画实现背景逐渐变暗
Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例
Laravel如何为API编写文档_Laravel API文档生成与维护方法
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
如何在云虚拟主机上快速搭建个人网站?
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
魔毅自助建站系统:模板定制与SEO优化一键生成指南
网易LOFTER官网链接 老福特网页版登录地址
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
如何快速搭建安全的FTP站点?
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
如何生成腾讯云建站专用兑换码?
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
如何实现javascript表单验证_正则表达式有哪些实用技巧
长沙企业网站制作哪家好,长沙水业集团官方网站?
Swift开发中switch语句值绑定模式
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
制作旅游网站html,怎样注册旅游网站?
JS中对数组元素进行增删改移的方法总结
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
Swift中swift中的switch 语句
用v-html解决Vue.js渲染中html标签不被解析的问题
jQuery中的100个技巧汇总
如何用5美元大硬盘VPS安全高效搭建个人网站?
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
EditPlus中的正则表达式 实战(2)
如何在VPS电脑上快速搭建网站?
如何在阿里云完成域名注册与建站?
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
php打包exe后无法访问网络共享_共享权限设置方法【教程】
浅述节点的创建及常见功能的实现
Laravel如何实现邮件验证激活账户_Laravel内置MustVerifyEmail接口配置【步骤】
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
深圳网站制作培训,深圳哪些招聘网站比较好?
上一篇: 怎么制作网站,怎样注册网站?
上一篇: 怎么制作网站,怎样注册网站?

