简单剖析Node中的事件监听机制(一)
使用js的class类简单的实现一个事件监听机制,不同于浏览器中的时间绑定与监听,类似于node中的时间监听,并且会在接下来的文章中去根据自己的理解去写一下Event模块中的原理。
Node.js使用了一个事件驱动、非阻塞式I/O的模型,使其轻量又高效。并且Node中的大量模块都使用了Event机制,因此可以说是整个Node中最重要的模块之一。
实例:
let event = new eventEmitter();
event.on('someType',function(){
});
event.emit('someType');
依据上述例子,手动触发一个类型的事件,调用监听的回调函数,可以先来实现一个最为简单的小例子,例如下放代码:
class eventEmitter {
constructor() {
this.callEvent = '';
}
on(eventType, callback) {
this.callEvent = callback;
};
emit(eventType) {
this.callEvent();
};
}
let event = new eventEmitter();
event.on('click', function () {
console.log('click')
});
event.emit('click');
上述实现的代码,能够简单的实现,当我们执行emit()方法时,去执行原本on()中传入的回调函数。
我们知道node中的Event模块是一个简单的事件监听模式的实现。Event模块中只提供了一个对象EventEmitter,EventEmitter的核心就是事件监听与事件触发的监听功能的封装。
EventEmitter可以让我们注册一个或者多个函数作为listeners,在特定的事件触发时被调用。我们去监听的函数就是listeners。当然,我们可以注册多个监听事件,所以需要一个map结构来存储监听事件和回调函数的对应关系。
在EventEmitter类中,已键值对的方式来存储事件名和对应的监听器。
首先根据上边的类来实现我们on事件,先来个events来作为存储的键值对,每次传入的值为事件类型和回调函数,代码简单如下:
EventEmitter.prototype.on = function on(type,listener){
return _on(this,type,listener);
};
function _on(target,type,listener){
var m;
var events;
var existing;
if(typeof listener !== 'function'){
throw new Error("监听者必须是一个函数");
}
//获取到对象上的监听事件键值对
events = target._events;
if(!events){
//如果没有键值对,则重新自定义
events = target._events = {};
target._eventsCount = 0;
}else{
//获取原来键值对中的listener事件
existing = events[type];
}
if(!existing) {
//如果原本的事件监听的键值对中没有该type的该监听事件
//则在events中存放该type和该监听事件的键值对
existing = events[type] = listener;
//并且当前内存中存放的监听事件加1
++target._eventsCount;
}
return target;
}
现在on事件可以使用了,我们先不去思考最大监听数的限制还有键值对的初始化不正确等其他因素,这些可以放在之后进行优化,接下来简单的去实现EventEmitter中的emit事件
EventEmitter.prototype.emit = function emit(type){
return _emit(this,type);
};
function _emit(target,type){
var events,exiting,handler;
if(!type){
throw new Error('触发的事件不能为空');
}
//获取到对象上的监听事件键值对
events = target._events;
//根据type获取到监听事件
handler = events[type];
if(!handler){
return false;
}
handler();
}
同样的emit事件的实现是简单的从键值对中根据type获取到监听事件去执行。这里还没有考虑传入多个参数的情况。
根据上边的简单实现,我们可以来进行下尝试,比之前的版本相比,我们可以监听多个事件,去触发多个回调函数了。
event.on('click', function () {
console.log('click')
});
event.on('click1',function (){
console.log('click11');
});
event.emit('click');
//输出click
event.emit('click1');
//输出click11
console.log(event._events);
//输入{click: [Function],click1:[Function]}
这里简单的实现了多个事件注册,多个事件触发的EventEmitter,接下来会继续进行设置监听个数、以及触发时传入多个参数的剖析。
参考:[https://github.com/nodejs/node/blob/v6.0.0/lib/events.js]
简单剖析Node中的事件监听机制(一)的更多相关文章
- Java中的事件监听机制
鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...
- Java 中的事件监听机制
看项目代码时遇到了好多事件监听机制相关的代码.现学习一下: java事件机制包含三个部分:事件.事件监听器.事件源. 1.事件:继承自java.util.EventObject类,开发人员自己定义. ...
- jQuery中的事件监听方式及异同点
jQuery中的事件监听方式及异同点 作为全球最知名的js框架之一,jQuery的火热程度堪称无与伦比,简单易学的API再加丰富的插件,几乎是每个前端程序员的必修课.从读<锋利的jQuery&g ...
- Java swing(awt):事件监听机制的实现原理+简单示例
(1)实现原理 事件监听机制的实现: 参考图:事件模型_ActionEvent 为了节省资源,系统无法对某个事件进行实时的监听.故实现的机制是当发生某个事件后,处理代码将被自动运行,类似钩子一般.(回 ...
- 创建图形用户界面GUI和事件监听机制的简单实现(java)
创建图形化界面 1.创建Frame窗体 2.对窗体进行基本设置 比如:大小.位置.布局 3.定义组件 4.将组建通过窗体添加到窗体中 5.让窗体显示,通过setVisib ...
- .NET事件监听机制的局限与扩展
.NET中把“事件”看作一个基本的编程概念,并提供了非常优美的语法支持,对比如下C#和Java代码可以看出两种语言设计思想之间的差异. // C#someButton.Click += OnSomeB ...
- java Gui编程 事件监听机制
1. GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式: 1. 命令交互方式 图书管理系统 ...
- JAVA之旅(三十一)——JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件
JAVA之旅(三十一)--JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件 有段时间没有更新JAVA了,我们今天来说一下JAVA中的图形化界面,也就是GUI ...
- JAVA 图形开发之计算器设计(事件监听机制)
/*文章中用到的代码只是一部分,需要源码的可通过邮箱联系我 1978702969@qq.com*/ 前段时间刚帮同学用MFC写了个计算器,现在学到JAVA的图形开发,就试着水了一个计算器出来.(可以说 ...
随机推荐
- 盘点:2016中国百强地产CIO高峰论坛的8大看点
2016年中国百强地产CIO高峰论坛将于2016年6月16日至18日在浙江湖州举行,届时百余位地产公司CIO将出席大会,共同探讨新形势下如何重塑IT价值,增强地产公司的市场竞争力和盈利能力. 此次大会 ...
- 分布式进阶(八)Linux提示Unable to locate package该如何处理?
Linux提示Unable to locate package该如何处理? 当你在修改Linux软件源的时候,提示Unable to locate package错误,这是由什么原因导致的呢?又该如何 ...
- 分布式进阶(二)Ubuntu 14.04下安装Dockr图文教程(一)
当前,完全硬件虚拟化技术(KVM.Xen.Hyper-V 等)能在一个物理主机上很好地运行多个互相独立的操作系统,但这也带来一些问题:性能不佳,资源浪费,系统反应迟缓等.有时候对用户来说,完全的硬件虚 ...
- ROS(indigo)_pr2_simulator仿真(gazebo)示例
ROS(indigo)_pr2_simulator仿真(gazebo)示例 1 开启pr2仿真 ~$ roslaunch gazebo_ros empty_world.launch ~$ roslau ...
- 如何利用BI搭建电商数据分析平台
某电商是某大型服装集团下的重要销售平台.2015 年,该集团品牌价值达数百亿元,产品质量.市场占有率.出口创汇.销售收入连年居全国绒纺行业第一,在中国有终端店3000多家,零售额80 亿.其羊绒制品年 ...
- Windows下配置nginx+FastCgi + Spawn-fcgi
前提: 下载nginx, FastCgi, Spawn-fcgi Spawn-fcgi有个Windows的版本,但不能在VS中编译,这里有一个编译好的版本:http://download.csdn.n ...
- Android 纵向跑马灯滚动效果
像淘宝和京东都会有跑马灯的效果,今天给大家贡献下以前项目的一个demo,各位看官,且看效果图. 我们先定义一个Bean文件,这个实体类文件主要包含标题,内容描述,以及还有跳转的链接. LampBean ...
- MPlayer 使用手册中文版
播放文件 使用 MPlayer 播放媒体文件最简单的方式是: mplayer <somefile> MPlayer 会自动检测文件的类型并加以播放,如果是音频文件,则会在命令行中显示该播放 ...
- saiku中文查询(鉴于有人提问:saiku执行mdx,有中文报错)
有人问我saiku的中文查询问题: saiku默认执行英文,很多人,在mysql里录入了中文,使用sql语言查询没有问题. 可是,用saiku的mdx查询,就会报错. 这是因为mysql默认支持中文查 ...
- Material Design之视图状态改变
视图状态改变是通过StateListAnimator动画集来改变View的状态的,它可以使View在不同状态下发生不同的变化,如下是在drawable目录下定义一个StateListAnimator: ...