位置: 编程技术 - 正文

详解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制作网站)

  • 外购配套费为什么不计利润
  • 减资需要交个税吗
  • 固定资产可以一次性摊销吗
  • 本年利润和利润分配未分配利润的区别
  • 研发支出月末结转转去哪里?
  • 篮球俱乐部是非洲的吗
  • 利润总额和未分配利润的公式
  • 以前年度管理费用多计
  • 收到社保中心的生育经贴怎么做账
  • 企业扣税账户没钱交税会怎么样?
  • 商品混凝土增值税政策
  • 公益性捐赠需要缴纳增值税吗
  • 电商销售进对公账户怎样做账
  • 专票遗失需要怎么处理?
  • 所得税费用可以抵减利润吗
  • 房租出租税收编码和税率
  • 企业自有固定资产有哪些
  • 工会经费计税依据是应发还是实发
  • 小规模纳税人出售使用过固定资产
  • 核定征收和查账征收,交的税一样吗
  • 工资的结转
  • 华为鸿蒙系统如何刷机
  • 金蝶固定资产减少怎么做
  • 什么叫交付使用
  • 上年预收账款算不算本年收入
  • 消耗性生物资产如何结转成本
  • qqexternal.exe是什么进程如何删除(CPU的使用率在90%)
  • 经营出租的机器设备需要计提折旧吗
  • 网络延迟高不稳定怎么办
  • 月末结转本年利润怎么算
  • 建筑业2021年享受核定征收吗
  • 计提工资个人所得税账务处理
  • bootstrap 栅格
  • 加盟代理需要什么手续
  • Blog2N如何计算
  • 什么情况下专票税率为1
  • 金税盘服务费分录
  • 企业对外报送的财务报表
  • jvm调优思路
  • python转换数字
  • 网约车提现多久到账
  • 农副产品免税了还需要缴纳个人所得税吗
  • 免税普票要交企业所得税吗
  • 国税局领发票是哪些项目需要收取费用
  • sqlserver数据库和mysql区别
  • 哪些所得需要去税务登记
  • 单位收到社保补贴会计怎样处理
  • 收到三代手续费如何入账
  • 银行结息交易是扣钱的意思吗
  • 现在增值税是多少个点
  • 月末结转的各类凭证无需注意先后顺序
  • 应收票据及应收账款怎么算
  • 装修设计费多少合理
  • 分批法成本核算对象
  • 外卖占比总营业额怎么算
  • 使用SSIS创建同步数据库数据任务的方法
  • sql server数据库使用
  • centos5.6
  • ubuntu中装虚拟机
  • 苹果mac 最新系统
  • 什么是selinux
  • win10太麻烦了
  • windows10x预览版
  • win8.1使用技巧
  • linux拉起进程
  • win7系统aero主题变成黑色
  • jquery生成div
  • ubuntu sudo apt-get install
  • unity如何调整界面
  • 调用m1方法
  • JavaScript中Number.MIN_VALUE属性的使用示例
  • javascript怎么学
  • javascript简明教程
  • 判断页面是关闭还是开启
  • email js
  • 疯狂android讲义和第一行代码
  • 京东发票税号是几位数
  • 辽宁税务微信公众号
  • 财产租赁包括哪些财产
  • 广东增值税发票勾选平台
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设