nodeJS中的事件机制
events模块是node的核心模块,几乎所有常用的node模块都继承了events模块,比如http、fs等。本文将详细介绍nodeJS中的事件机制
EventEmitter
多数 Node.js 核心 API 都是采用惯用的异步事件驱动架构,其中某些类型的对象(称为触发器)会周期性地触发命名事件来调用函数对象(监听器)。例如,一个net.Server对象会在每次有新连接时触发一个事件;一个fs.ReadStream 会在文件被打开时触发一个事件;一个stream会在数据可读时触发事件。
【EventEmitter】
EventEmitter 类由 events 模块定义和开放的,所有能触发事件的对象都是 EventEmitter 类的实例
var EventEmitter = require('events');
/*
{ [Function: EventEmitter]
EventEmitter: [Circular],
usingDomains: false,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] }
*/
console.log(EventEmitter);
events模块的EventEmitter属性指向该模块本身
var events = require('events');
console.log(events.EventEmitter === events);//true
EventEmitter是一个构造函数,可以用来生成事件发生器的实例emitter
var EventEmitter = require('events');
var emitter = new EventEmitter();
/*
EventEmitter {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined }
*/
console.log(emitter);
方法
【emitter.emit(eventName[, …args])】
eventName <any>
...args <any>
该方法按监听器的注册顺序,同步地调用每个注册到名为eventName事件的监听器,并传入提供的参数。如果事件有监听器,则返回true,否则返回false
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test1',function(){});
console.log(emitter.emit('test1'));//true
console.log(emitter.emit('test2'));//false
【emitter.on(eventName, listener)】
该方法用于添加listener函数到名为eventName的事件的监听器数组的末尾
eventName <any> 事件名
listener <Function> 回调函数
注意:不会检查listener是否已被添加。多次调用并传入相同的eventName和listener会导致listener被添加与调用多次
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
});
emitter.on('test',function(){
console.log(2);
});
emitter.emit('test');//1 2
该方法返回一个 EventEmitter 引用,可以链式调用
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
}).on('test',function(){
console.log(2);
});
emitter.emit('test');//1 2
【emitter.addListener(eventName, listener)】
emitter.on(eventName, listener) 的别名
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.addListener('test',function(){
console.log(1);
});
emitter.emit('test');//1
【emitter.prependListener()】
与on()方法不同,prependListener()方法可用于将事件监听器添加到监听器数组的开头
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
}).prependListener('test',function(){
console.log(2);
});
emitter.emit('test');//2 1
【emitter.once(eventName, listener)】
该方法添加一个单次 listener 函数到名为 eventName 的事件。 下次触发 eventName 事件时,监听器会被移除,然后调用
eventName <any> 事件名
listener <Function> 回调函数
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
}).once('test',function(){
console.log(2);
});
emitter.emit('test');//1 2
emitter.emit('test');//1
【emitter.prependOnceListener() 】
该方法用于将事件监听器添加到监听器数组开头。下次触发eventName事件时,监听器会被移除,然后调用
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
}).prependOnceListener('test',function(){
console.log(2);
});
emitter.emit('test');//2 1
emitter.emit('test');//1
【emitter.removeAllListeners([eventName])】
eventName <any>
移除全部或指定 eventName 的监听器,返回一个 EventEmitter 引用,可以链式调用
注意:在代码中移除其他地方添加的监听器是一个不好的做法,尤其是当 EventEmitter 实例是其他组件或模块(如 socket 或文件流)创建的
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
}).removeAllListeners('test');
emitter.emit('test');//''
【emitter.removeListener(eventName, listener)】
eventName <any>
listener <Function>
从名为 eventName 的事件的监听器数组中移除指定的 listener
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
}).prependListener('test',function(){
console.log(2);
});
emitter.emit('test');//2 1
注意:removeListener最多只会从监听器数组里移除一个监听器实例。如果任何单一的监听器被多次添加到指定eventName的监听器数组中,则必须多次调用removeListener才能移除每个实例
var EventEmitter = require('events');
var emitter = new EventEmitter();
function show(){
console.log(1);
}
emitter.on('test',show).on('test',show).removeListener('test',show);
emitter.emit('test');//'1'
注意:一旦一个事件被触发,所有绑定到它的监听器都会按顺序依次触发。这意味着,在事件触发后、最后一个监听器完成执行前,任何 removeListener() 或 removeAllListeners() 调用都不会从 emit() 中移除它们。 随后的事件会像预期的那样发生
因为监听器是使用内部数组进行管理的,所以调用它会改变在监听器被移除后注册的任何监听器的位置索引。 虽然这不会影响监听器的调用顺序,但意味着由 emitter.listeners() 方法返回的监听器数组副本需要被重新创建
var EventEmitter = require('events');
var emitter = new EventEmitter();
function show1(){
console.log(1);
emitter.removeListener('test',show2);
}
function show2(){
console.log(2);
}
emitter.on('test',show1).on('test',show2);
emitter.emit('test');//1 2
emitter.emit('test');//1
nodeJS中的事件机制的更多相关文章
- NodeJS 中的事件循环,读了这篇就全懂了
事件循环是 NodeJS 处理非阻塞 I/O 操作的和核心机制.NodeJS 的事件循环脱胎于 libuv 的事件循环,因此,要搞清楚 NodeJS 的事件循环,还需要先了解 libuv 的事件循环是 ...
- jQuery中的事件机制深入浅出
昨天呢,我们大家一起分享了jQuery中的样式选择器,那么今天我们就来看一下jQuery中的事件机制,其实,jQuery中的事件机制与JavaScript中的事件机制区别是不大的,只是,JavaScr ...
- Tomcat与Spring中的事件机制详解
最近在看tomcat源码,源码中出现了大量事件消息,可以说整个tomcat的启动流程都可以通过事件派发机制串起来,研究透了tomcat的各种事件消息,基本上对tomcat的启动流程也就有了一个整体的认 ...
- Spring 中的事件机制
说到事件机制,可能脑海中最先浮现的就是日常使用的各种 listener,listener去监听事件源,如果被监听的事件有变化就会通知listener,从而针对变化做相应的动作.这些listener是怎 ...
- NodeJS中的事件
/** * Created by xiwu.xxw on 2015/7/22. */ /** * EventEmitter 的每个事件由一个事件名和若干个参数组成, * 事件名是一个字符串,通常表达一 ...
- javascript 中的事件机制
1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...
- libevent中的事件机制
libevent是事件驱动的网络库,事件驱动是他的核心,所以理解事件驱动对于理解整个网络库有很重要的意义. 本着从简入繁,今天分析下单线程最简单的事件触发.通过sample下的event- ...
- Flex中利用事件机制进行主程序与子窗体间参数传递
在开发具有子窗体,或者itemrenderer的应用时,常常涉及到子窗体向父窗体传递参数或者从itemrenderer内的控件向外部的主程序传递参数的需求.这些都可以通过事件机制这一统一方法加以解决. ...
- nodejs 中自定义事件
经常看到 req.on('error', function(){...}); 这种代码. 在nodejs中,可以使用 EventEmitter来实现. 具体的关键词有如下几个: var reqEven ...
随机推荐
- 数据丢失如何恢复?EasyRecovery帮你快速实现
在日常使用电脑时,我们经常会遇到误删文件的情况,若文件还未被彻底删除,我们还可以通过电脑中的回收站将其恢复,但若是回收站都被清空的话,想要恢复文件就变得比较困难了,而EasyRecovery可以很好的 ...
- jQuery 第四章 实例方法 DOM操作之data方法
jquery 里面 的 data 方法比较重要, 所以成一个模块写: 首先, 得知道 data() 干嘛用的, 看淘宝上 有自定义的属性, 为data - 什么什么, 这是为了dom 跟数据有 ...
- java41
2019.8.7全部回顾完毕 收获:搞懂了以前不理解的内容 学会了Markdown语法 1. 将首字母变大写 public class _02将首字母变大写 { public static void ...
- 渗透入门rop
原文链接:https://blog.csdn.net/guiguzi1110/article/details/77663430?locationNum=1&fps=1 基本ROP 随着NX保护 ...
- 【进阶之路】定时任务调用平台xxl-job
大家好,我是练习java两年半时间的南橘,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西.知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了 ...
- Hyper-V 中设置虚拟机静态 IP
一.新建虚拟网络交换机 二.配置网络 网络共享默认使用 192.168.137.0/255 作为内网地址,192.168.137.1 作为网关 三.配置虚拟机静态 IP 安装完成虚拟机后修改配置文件: ...
- 第15.36节 PyQt(Python+Qt)入门学习:containers容器类部件QFrame框架部件介绍
一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有如下: 容器中的Frame为一个矩形的框架对象,对应类QFrame,QFrame类是PyQt中带框架 ...
- PyQt(Python+Qt)学习随笔:树型部件的QTreeWidgetItem项中列不同角色数据的有关访问方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 树型部件QTreeWidget中的QTreeWidgetItem项中可以有多列数据,每列数据可以根据 ...
- Python学习随笔:使用xlwings读取和操作Execl文件的数字需要注意的问题
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在使用xlwings读取Excel文件中的数据时,所有的数字不论是整数.浮点数还是文本存放的数字,在 ...
- 第15.4节 PyCharm程序代码检测功能介绍
老猿使用PyCharm有将近一个月了,发现PyCharm并不能很好的完成语法检查,有时运行时突然终止,仔细核查却发现是基本的语法错误,不过有次无意中移动鼠标到代码最右边的边框时发现其实PyCharm有 ...