参考:

1. Node.js之EventEmiter讲解

2. Node.js之events事件

3. 在线运行node.js代码

Node.js主要API使用异步事件驱动模型,异步I/O操作完成时,或者某些类型对象(触发器)会周期性地,触发一个命名事件到事件队列,用来调用函数对象(监听器)。

比如net.Server对象在每次有新连接时触发一个事件,fs.readStream对象在文件打开时触发一个事件。

所有这些能产生事件的对象都是events.EventEmitter的实例。

所有这些对象开放接口:

1. 注册事件名&监听器

on()注册一个事件(名)和一个监听器,添加到监听器数组末尾,addListener()是on()的别名。emit(), 按顺序执行每个监听器。

eventEmitter.on()  // 绑定事件名&监听器

demo source code:

var events = require('events');
var eventEmitter = new events.EventEmitter;
eventEmitter.on('start', function() {
console.log('eventEmitter starts');
});
eventEmitter.emit('start');

运行结果(打印):

eventEmitter starts

2. 给监听器listener传入参数与this

emit方法允许给监听器传入任意参数,并且标准this会被设置为监听器所附加的EventEmitter。

demo:

var events = require('events');
var eventEmitter = new events.EventEmitter;
eventEmitter.on('start', function(a,b) {
console.log('eventEmitter starts');
console.log(a,b,this);
});
eventEmitter.emit('start','a','b');

运行结果(打印):

eventEmitter starts
a b { domain: null,
_events: { start: [Function] },
_maxListeners: 10 }

3. 最多只触发一次的监听器

on注册的监听器可以触发多次,once注册的最多触发一次。

demo

var events = require('events');
var eventEmitter = new events.EventEmitter;
//用on注册事件,绑定监听器
eventEmitter.on('start', function() {
console.log('eventEmitter starts');
});
eventEmitter.emit('start');
eventEmitter.emit('start'); //用once注册事件,绑定监听器
eventEmitter.once('do', function() {
console.log('eventEmitter do');
});
eventEmitter.emit('do');
eventEmitter.emit('do');

运行结果输出:

eventEmitter starts
eventEmitter starts
eventEmitter do

4. 错误事件

EventEmitter实例发生错误时,会触发名为‘error’的特殊事件。

为防止node.js程序崩溃,建议始终为'error'事件注册监听器。

var events = require('events');
var eventEmitter = new events.EventEmitter;
//用on注册事件,绑定监听器
eventEmitter.on('error', function(err) {
console.log('eventEmitter err occurs');
});
eventEmitter.emit('error', new Error('programme exception'));

运行输出结果:

eventEmitter err occurs

5. 添加监听器/移除监听器事件

当新增监听器时,所有EventEmitter会触发'newListener'事件;当移除监听器时,会触发'removeListener'事件。

demo

var events = require('events');
var eventEmitter = new events.EventEmitter;
//用once注册事件,只会执行一次
eventEmitter.once('newListener', function(event, listener) {
if(event=='start') {
eventEmitter.on('start',function(){
console.log('start 2');
});
console.log('start');
}
});
eventEmitter.on('start',function(){
console.log('eventEmitter start');
}); eventEmitter.emit('start');

运行输出:

start
start 2
eventEmitter start

可以看到,触发‘start’事件,会同时触发'newListener'事件,并且on注册事件不会等待,而是直接执行后面的语句。

newListener&removeListener事件触发源
事件名 触发源 备注
newListener

addListener() on()别名
on()  
once() 只执行一次便自行注销
removeListener removeListener()  
removeAllListeners()  
off()

removeListener()别名,v10.0.0添加

6. 最大监听器数量

获取最大监听器数量getMaxListeners(),v1.0.0 API才有用,老版本nodejs可能会有编译错误。超出最大数量限制时,可以调用setMaxListeners()重新设置更大值。

Node.js之EventEmiter的更多相关文章

  1. Node.js小白开路(一)-- events篇

    时间或许可以说是以JS来理解世界的基础,针对于某一个情况对象会做出何种反应,反应之后会做出何种处理,以及这一事件衍生出来了哪一些变化. 大多数 Node.js 核心 API 都采用惯用的异步事件驱动架 ...

  2. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  3. 利用Node.js的Net模块实现一个命令行多人聊天室

    1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...

  4. Node.js:进程、子进程与cluster多核处理模块

    1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...

  5. Node.js:理解stream

    Stream在node.js中是一个抽象的接口,基于EventEmitter,也是一种Buffer的高级封装,用来处理流数据.流模块便是提供各种API让我们可以很简单的使用Stream. 流分为四种类 ...

  6. Node.js:Buffer浅谈

    Javascript在客户端对于unicode编码的数据操作支持非常友好,但是对二进制数据的处理就不尽人意.Node.js为了能够处理二进制数据或非unicode编码的数据,便设计了Buffer类,该 ...

  7. node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法

    1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...

  8. Node.js npm 详解

    一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...

  9. Node.js入门(一)

    一.Node.js本质上是js的运行环境. 二.可以解析js代码(没有浏览器安全级的限制): 提供系统级的API:1.文件的读写 2.进程的管理 3.网络通信 三.可以关注的四个网站: 1.https ...

随机推荐

  1. [踩坑记录] windows10 应用商店打不开 代码: 0x80131500

    在某博客看到的方法,供参考,可以尝试一下,我的也是这么解决的1.打开“运行”输入 inetcpl.cpl (“WINDOWS”+“R”键,输入 inetcpl.cpl亦可)2.点开高级往下拉,勾上&q ...

  2. 吴裕雄 python 神经网络TensorFlow实现LeNet模型处理手写数字识别MNIST数据集

    import tensorflow as tf tf.reset_default_graph() # 配置神经网络的参数 INPUT_NODE = 784 OUTPUT_NODE = 10 IMAGE ...

  3. 提高Scrapy爬取效率

    1.增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100. 2.降低 ...

  4. 例题3_1 TeX中的引号(TeX Quotes,UVa 272)

    在TeX中,左双引号是“``”,右双引号是“''”.输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式. 样例输入: "To be or not to be,"quoth ...

  5. Python NumPy中数组array.min(0)返回数组

    如果没有参数min()返回一个标量,如果有参数0表示沿着列,1表示沿着行.

  6. ubuntu 18 python3.6更换国内源和pip3源

    1.更换国内源 查看Ubuntu18版本和codename(一定要注意codename对应) lsb_release -a No LSB modules are available. Distribu ...

  7. 【原】Django总结

    centos7下部署django详细步骤:https://www.cnblogs.com/djangocn/p/9538551.html 快速入门:https://www.cnblogs.com/ze ...

  8. 【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))

    题意: 输入一个包含空格的字符串,输出它的最长回文子串的长度. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC #include<bits/std ...

  9. html js中的引号

    content = "<a class='btn' href='javascript:void(0)' onclick='change('orders/orderTail.do?ode ...

  10. Start from here: <<OpenGL的基本程序解析>>

    这是我的第一篇学习OpenGL的笔记,也是博主的第一篇博客,希望能够在这里和大家一起成长. 下面的代码是<OpenGL超级宝典(第五版)>中的示例代码,基本程序如下: #include & ...