位置: 编程技术 - 正文

详解Node.js中的事件机制(node.js deno)

编辑:rootadmin

推荐整理分享详解Node.js中的事件机制(node.js deno),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:node.js gui,node.js deno,node.js的作用,node.js使用教程,node.js javascript,node-js,node.js的作用,node.js deno,内容如对您有帮助,希望把文章链接给更多的朋友!

前言

在前端编程中,事件的应用十分广泛,DOM上的各种事件。在Ajax大规模应用之后,异步请求更得到广泛的认同,而Ajax亦是基于事件机制的。

通常js给我们的第一印象就是运行在客户端浏览器上面的脚本,通过node.js我们可以在服务端运行javascript.

node.js是基于单线程无阻塞异步式的I/O,异步式的I/O指的是当遇到I/O操作的时候,线程不阻塞而是进行下面的操作,那么I/O操作完成之后,线程时如何知道该操作完成的呢?

当操作完成耗时的I/O操作之后,会以事件的形式通知I/O操作的线程完成,线程会在特定的时候来处理这个事件,进行下一步的操作,为了完成异步I/O,线程必须有事件循环的机制,不停的坚持是否有没有完成的事件,依次完成这些事件的处理。

而对于阻塞式I/O,线程遇到耗时的I/O操作会停止继续执行,等待操作的完成,这个时候线程就不能接受其他的操作请求,为了提供吞吐量,必须创建多个线程,每个线程去响应一个客户的请求,但是同一时间,一个cpu核心上面只能运行一个线程,多个线程要想执行就必须在不同的线程之间进行切换。

因此node.js少了多线程中线程的创建,以及线程的切换的开销,线程切换的代价是非常大的,需要为其分配内存,列入调度,同时在线程切换的时候需要执行内存换页等等操作,采用单线程的方式就可以减少这些操作。但是这种编程方式也有缺点,不符合人们的设计思维。

node.js是基于事件的模式来实现异步I/O的,当其启动之后会不停的遍历是否有为完成的事件,然后进行执行,执行完成之后会以另外一个事件的形式通知线程,本操作已经完成,这个事件又会被添加到未完成的事件列表中,线程在接下来的某个时刻遍历到这个事件然后进行执行,在这种机制中,需要将一个大的任务分成一个个小的事件,node.js也适合处理一些高I/O,低逻辑的场景。

下面的例子演示异步的文件读取:

如上fs.readFile异步读取文件,之后流程就会继续走,并不会等待其读取完文件,当文件读取完毕之后,会发布一个事件,执行线程遍历到该事件就会去执行对应的操作,这里是执行相应的回调函数,例子中字符串end会比文件内容先打印出来。

node.js的事件API

events.EventEmitter:EventEmitter对node.js中的事件发射与事件监听功能提供了封装,每个事件由一个标识事件名的字符串和对应的操作组成。

事件的监听:

事件的发布:

发布事件的时候我们可以传入多个参数,第一个参数表示事件的名称,其后的参数表示传入的参数,这些参数会被传入到事件的回调函数中。

EventEmitter.once("eventName", listener) :为事件注册一个只执行一次的监听器,当事件第一次发生并触发监听器之后,该监听器就会解除,之后如果事件发生,该监听器不会执行。

详解Node.js中的事件机制(node.js deno)

EventEmitter.removeListener(event, listener) :移除掉事件的监听器

EventEmitter.removeAllListeners(event) :移除掉事件的所有的监听器

EventEmitter.setMaxListeners(n) :node.js默认单个事件最大的监听器个数是,如果超过会给予警告,这么做是为了防止内存的溢出,我们可以更改这种限制设置为其他的数字,如果设置为0表示不进行限制。

EventEmitter.listeners(event) :返回某个事件的监听器列表

多事件之间协作在略微大一点的应用中,数据与Web服务器之间的分离是必然的,如新浪微博、Facebook、Twitter等。这样的优势在于数据源统一,并且可以为相同数据源制定各种丰富的客户端程序。

以Web应用为例,在渲染一张页面的时候,通常需要从多个数据源拉取数据,并最终渲染至客户端。Node.js在这种场景中可以很自然很方便的同时并行发起对多个数据源的请求。

Node.js通过异步机制使请求之间无阻塞,达到并行请求的目的,有效的调用下层资源。但是,这个场景中的问题是对于多个事件响应结果的协调并非被Node.js原生优雅地支持。

为了达到三个请求都得到结果后才进行下一个步骤,程序也许会被变成以下情况:

这将导致请求变为串行进行,无法最大化利用底层的API服务器。

为解决这类问题,我曾写作一个模块来实现多事件协作,以下为上面代码的改进版:

EventProxy也是一个简单的事件侦听者模式的实现,由于底层实现跟Node.js的EventEmitter不同,无法合并进Node.js中。但是却提供了比EventEmitter更强大的功能,且API保持与EventEmitter一致,与Node.js的思路保持契合,并可以适用在前端中。这里的all方法是指侦听完profile、timeline、skin三个方法后,执行回调函数,并将侦听接收到的数据传入。

最后还介绍一种解决多事件协作的方案,通过运行时编译的思路(需要时也可在运行前编译),将同步思维的代码转换为最终异步的代码来执行,可以在编写代码的时候通过同步思维来写,可以享受到同步思维的便利写作,异步执行的高效性能。

如果通过Jscex编写,将会是以下形式:

利用事件队列解决雪崩问题

所谓雪崩问题,是在缓存失效的情景下,大并发高访问量同时涌入数据库中查询,数据库无法同时承受如此大的查询请求,进而往前影响到网站整体响应缓慢。

那么在Node.js中如何应付这种情景呢。

以上是一句数据库查询的调用,如果站点刚好启动,这时候缓存中是不存在数据的,而如果访问量巨大,同一句SQL会被发送到数据库中反复查询,影响到服务的整体性能。一个改进是添加一个状态锁。

但是这种情景,连续的多次调用select发,只有第一次调用是生效的,后续的select是没有数据服务的。所以这个时候引入事件队列吧:

这里利用了EventProxy对象的once方法,将所有请求的回调都压入事件队列中,并利用其执行一次就会将监视器移除的特点,保证每一个回调只会被执行一次。对于相同的SQL语句,保证在同一个查询开始到结束的时间中永远只有一次,在这查询期间到来的调用,只需在队列中等待数据就绪即可,节省了重复的数据库调用开销。由于Node.js单线程执行的原因,此处无需担心状态问题。这种方式其实也可以应用到其他远程调用的场景中,即使外部没有缓存策略,也能有效节省重复开销。此处也可以用EventEmitter替代EventProxy,不过可能存在侦听器过多,引发警告,需要调用setMaxListeners(0)移除掉警告,或者设更大的警告阀值。

总结

标签: node.js deno

本文链接地址:https://www.jiuchutong.com/biancheng/370801.html 转载请保留说明!

上一篇:详解Node.Js如何处理post数据(node. js教程)

下一篇:利用Node.js制作爬取大众点评的爬虫(nodejs制作网站)

  • 房地产开发企业土地增值税预缴
  • 计入职工福利费的有哪些
  • 宁波财税网会计招聘
  • 个税app正式启用
  • 收到订金如何开票
  • 应纳税所得额的计算公式
  • 小规模纳税人税控盘怎么做账
  • 老师课时费计入什么科目
  • 实收资本未完全到账,需要缴纳印花税吗
  • 固定资产所取得的成本
  • 出售办公用房要交什么税
  • 其他应收款属于流动资产吗
  • 劳动仲裁是怎样仲裁公司的
  • 预收房款什么意思
  • 个体工商户税务登记证需要什么资料
  • 假设公司为增值税一般纳税人
  • 问福利费的发票如果是增值税专用发票,增值税可以抵扣吗?
  • 外汇汇率在其中扮演什么角色?
  • 电子发票能报税不
  • 建筑设计公司的账务处理
  • 进项税额加计扣除分录
  • 贷款利率计算公式表格
  • 不动产抵押合同管辖法院
  • 报销冲销借款
  • 出租的厂房房产税谁交
  • linux设置权限规则
  • mac屏幕横过来了
  • 简易计税方法的适用主体有
  • messenger 是什么意思
  • 年营业收入平均增长
  • 融资租入固定资产是什么意思
  • 会计核算的实训目的
  • 三维目标通用模板
  • 纳税调整增加额怎么做会计分录
  • 债券投资账务处理例题
  • 专项储备怎么理解
  • php如何防止后门
  • 搜索人工制造
  • java泛型类和泛型方法
  • 微服务docker打包规范
  • 广告公司纳税人类型
  • 每个季度30万免增值税
  • 综合所得计税依据
  • 资产负债表其他应付款怎么填
  • 应交税费的明细账怎么登记
  • 代宰 增值税
  • 盈余公积转增资本所有者权益会变吗
  • 土增清算后后续成本计算
  • access数据库丢失原因
  • 退去年的销售账务如何处理
  • 免费赠送客户入群的文案
  • 付款申请单如何管理
  • 代金券抵帐怎么退款
  • 固定资产的后续支出应如何进行会计处理
  • 建筑行业有哪些生意可以做
  • 确认代销手续费怎么做账
  • 单位收走三方协议
  • 公司建账初期做账怎么做
  • 农业机耕属于种植业吗
  • 老板用公司的钱算挪用公款吗
  • mysql数据库迁移上云
  • mysql中字符串类型
  • win7回收站路径在哪里
  • 桌面美化助手
  • linuxdhcp服务器管理与配置
  • linux %1
  • win7 u盘不显示
  • cocos2dx安装和初步使用
  • opengl怎么导入模型
  • js调用wsdl接口
  • js取二维数组数组的值
  • .nodejs
  • js设置页面大小
  • html5游戏引擎排行
  • Android之SQLite
  • dom,ran
  • adb命令ls
  • 地税局公务员考试科目
  • 广东省税务总局局长叫什么名
  • 北京市税务局热搜
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设