位置: 编程技术 - 正文

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

  • 法律会计审计咨询合同需要缴纳印花税吗
  • 外出经营活动税收管理证明在哪里办理
  • 开民工工资专户
  • 本期应补退税额怎么算
  • 没有数字的公章有效吗三方协议盖的章没有数字
  • 医院工作服记什么科目
  • 油费补贴计入什么科目
  • 资金结存期末余额方向
  • 金税盘费服务费记入什么科目
  • 怎么识别发票是否含税
  • 发票领回来了怎么读入发票
  • 增值税发票选择确认平台勾选注意事项
  • 外商企业增资
  • 无偿划拨资产涉税问题
  • 结转本月工资薪金
  • 施工单位奖金分配方案
  • 关于销售返利的说法正确的有
  • 营改增后机械设备租赁需缴纳什么税?
  • 安徽附加税优惠政策
  • 小规模纳税人和小微企业区别
  • 企业所得税一般是几个点
  • 住房公积金做账怎么看交了哪些人
  • 工地没有手续擅自开工违法吗
  • 税控设备指什么
  • 公允价值变动损益借贷方向
  • 该设备正在使用中怎么关闭u盘
  • 生产测试是指什么
  • 什么是土地使用者依照法律规定
  • 苹果mac修改用户名和密码
  • 错误代码:0x0000428
  • 系统自带功能
  • 2017年8月21日是什么日子
  • 详解九章算法
  • 国家规定免税饲料具体哪些产品
  • 房地产开发企业增值税怎么算
  • vue中如何使用axios
  • 行政单位捐赠收入属于什么收入
  • ThinkPHP中Common/common.php文件常用函数功能分析
  • vget命令
  • pandas模块的主要特点
  • 向股东免息借款怎么做账
  • 交通费 抵扣
  • 什么情况下需要做肠胃镜
  • sql2008自动启动服务
  • SqlServer 2005 T-SQL Query 学习笔记(4)
  • 跨月凭证怎么冲销
  • 交易性金融资产公允价值变动怎么算
  • 现金折扣要扣除折扣金额入账吗
  • 其他综合收益转到留存收益
  • 采用账龄分析法计提坏账准备时,收到
  • 公司开业前期费用谁出
  • 长期股权投资减值准备
  • 补交以前年度环保税
  • 其他业务收入的附加税的会计分录
  • 银行手续费没拿可以退吗
  • 财政拨款结转是
  • 质保金可以先不开票吗
  • 个人股权激励收入税率
  • 个体工商户的纳税标准
  • 公司房屋租赁协议
  • 在MySQL中使用GTIDs复制协议和中断协议的教程
  • mac忘记mysql初始密码
  • 开启 windows server
  • solaris date命令
  • 光盘安装系统怎么操作
  • 怎么用手机号查快递
  • efi怎么安装系统
  • 做ghost备份
  • unetbootin教程
  • mac 钥匙串访问
  • Win7系统打开文件夹没有自动排列选项
  • win8.1系统要求配置
  • css ul显示为表格
  • jQuery on绑定的事件
  • 计算天数的excel公式
  • js新开一个窗口
  • python的异常处理语句
  • gpu解码视频
  • 安卓打包安装程序apk
  • 绿牌电动车需要什么条件
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设