前面的话

  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');//

【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');//

【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');//

【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();
function show(){
console.log(1);
}
emitter.on('test',show).removeListener('test',show);
emitter.emit('test');//''

  [注意]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');//

设置

【emitter.eventNames()】

  返回一个列出触发器已注册监听器的事件的数组。 数组中的值为字符串或符号

var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.addListener('test1',function(){console.log(1);});
emitter.addListener('test2',function(){console.log(2);});
console.log(emitter.eventNames());//[ 'test1', 'test2' ]

【emitter.listenerCount(eventName)】

eventName <any> 正在被监听的事件名

  返回正在监听名为 eventName 的事件的监听器的数量

var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.addListener('test',function(){console.log(1);});
emitter.addListener('test',function(){console.log(1);});
console.log(emitter.listenerCount('test'));//

【emitter.listeners(eventName)】

eventName <any>

  返回名为 eventName 的事件的监听器数组的副本

var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.addListener('test',function(){console.log(1);});
emitter.addListener('test',function(){console.log(2);});
console.log(emitter.listeners('test'));//[ [Function], [Function] ]
emitter.listeners('test')[0]();//

【emitter.getMaxListeners()】

  返回 EventEmitter 当前的最大监听器限制值

var EventEmitter = require('events');
var emitter = new EventEmitter();
console.log(emitter.getMaxListeners());//

【emitter.setMaxListeners(n)】

  默认情况下,如果为特定事件添加了超过 10 个监听器,则 EventEmitter 会打印一个警告。 此限制有助于寻找内存泄露。 但是,并不是所有的事件都要被限为 10 个。 emitter.setMaxListeners() 方法允许修改指定的 EventEmitter 实例的限制。 值设为 Infinity(或 0)表明不限制监听器的数量。返回一个 EventEmitter 引用,可以链式调用

var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){});
/*
Warning: Possible EventEmitter memory leak detected. 11 a listeners added. Use emitter.setMaxListeners() to increase limit
*/
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.setMaxListeners(11);
emitter.on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){});

【EventEmitter.defaultMaxListeners】
  每个事件默认可以注册最多10个监听器。单个EventEmitter实例的限制可以使用emitter.setMaxListeners(n)方法改变。所有EventEmitter实例的默认值可以使用EventEmitter.defaultMaxListeners属性改变

  [注意]设置 EventEmitter.defaultMaxListeners 要谨慎,因为会影响所有EventEmitter 实例,包括之前创建的。因而,调用 emitter.setMaxListeners(n) 优先于 EventEmitter.defaultMaxListeners

var EventEmitter = require('events');
var emitter = new EventEmitter();
EventEmitter.defaultMaxListeners = 11;
emitter.on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){}).on('a',function(){});

事件

【'newListener' 事件】

eventName <any> 要监听的事件的名称
listener <Function> 事件的句柄函数

  EventEmitter 实例会在一个监听器被添加到其内部监听器数组之前触发自身的 'newListener' 事件

  注册了 'newListener' 事件的监听器会传入事件名与被添加的监听器的引用。事实上,在添加监听器之前触发事件有一个微妙但重要的副作用: 'newListener' 回调中任何额外的被注册到相同名称的监听器会在监听器被添加之前被插入

var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('newListener',function(){
console.log(2);
})
emitter.on('test',function(){
console.log(1);
}) emitter.emit('test');//2 1
var EventEmitter = require('events');
var emitter = new EventEmitter();
emitter.on('test',function(){
console.log(1);
})
emitter.on('newListener',function(){
console.log(2);
})
emitter.emit('test');//

【'removeListener' 事件】

eventName <any> 事件名
listener <Function> 事件句柄函数

  'removeListener' 事件在 listener 被移除后触发

var EventEmitter = require('events');
var emitter = new EventEmitter();
function show(){
console.log(1);
}
emitter.on('removeListener',function(){
console.log(2);//
})
emitter.on('test',show).removeListener('test',show);
var EventEmitter = require('events');
var emitter = new EventEmitter();
function show(){
console.log(1);
}
emitter.on('test',show).removeListener('test',show);
emitter.on('removeListener',function(){
console.log(2);//''
})
var EventEmitter = require('events');
var emitter = new EventEmitter();
function show(){
console.log(1);
}
emitter.removeListener('test',show);
emitter.on('removeListener',function(){
console.log(2);//''
})

nodeJS之事件events的更多相关文章

  1. nodejs触发事件的两种方式

    nodejs触发事件的两种方式: 方式之一:通过实例化events.EventEmitter //引入events模块 var events = require('events'); //初始化eve ...

  2. 深入出不来nodejs源码-events模块

    这一节内容超级简单,纯JS,就当给自己放个假了,V8引擎和node的C++代码看得有点脑阔疼. 学过DOM的应该都知道一个API,叫addeventlistener,即事件绑定.这个东西贯穿了整个JS ...

  3. MySQL事件 Events

    MySQL事件 Events   一.关键字: EVENT   二.语法: CREATE EVENT? [IF NOT EXISTS ] //如果不存在则创建 event_name? ON SCHED ...

  4. openwrt gstreamer实例学习笔记(七. gstreamer 缓冲区(Buffers)和事件(Events))

    1)概述 管道的数据流由一组缓冲区和事件组成,缓冲区包括实际的管道数据,事件包括控制信息,如寻找信息和流的终止信号.所有这些数据流在运行的时候自动的流过管道. 2) 缓冲区(Buffers) 缓冲区包 ...

  5. jquery 选择器(selector)和事件(events)

    页面加载完成后开始运行do stuff when DOM is ready 中的语句! $(document).ready(function() {       // do stuff when DO ...

  6. 面试题: nodejs 的事件轮询机制

    setTimeout(function(){ console.log('setTimeout()执行了') },0) setImmediate(function(){ console.log('set ...

  7. Nodejs学习事件模块

    1.nodejs 版本为v6.2.0,events是node.js 最重要的模块,events模块只提供了一个对象EventEmitter,EventEmitter 的核心是事件发射与事件监听器.可以 ...

  8. 使用nodejs+http(s)+events+cheerio+iconv-lite爬取2717网站图片数据到本地文件夹

    源代码如下:   //(node:9240) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' ...

  9. nodejs学习之events的使用

    实用events做个小例子: var mysql = require("mysql"); var Event = require("events").Event ...

随机推荐

  1. jquery使用CSS3实现文字动画效果插件Textillate.js

    Textillate是一款基于jquery的使用CSS3实现文字动画的小巧插件.Textillate.js集成了一些很棒的使用CSS3动画效果的 JavaScript 库,您可非常轻轻松地把这些动画效 ...

  2. 实时Android语音对讲系统架构

    本文属于Android局域网内的语音对讲项目系列,<通过UDP广播实现Android局域网Peer Discovering>实现了局域网内的广播及多播通信,本文将重点说明系统架构,音频信号 ...

  3. require.js+bootstrap实现简单的页面登录和页面跳转

    小颖的这个demo其实很简单的,大家一起来先来看看页面效果图:          目录: 代码: inde.html <!DOCTYPE html> <html> <he ...

  4. MySQL之使用DDL语句创建表

    一.使用DDL语句创建表 DDL语言全面数据定义语言(Data Define Language) 主要的DDL动词: CREATE(创建).DROP(删除).ALTER(修改) TRUNCATE(截断 ...

  5. 【算法系列学习】Dijkstra求最短路 [kuangbin带你飞]专题四 最短路练习 D - Silver Cow Party

    https://vjudge.net/contest/66569#problem/D trick:1~N各点到X可以通过转置变为X到1~N各点 #include<iostream> #in ...

  6. app性能测试【通过loadrunner录制】

    随着智能手机近年来的快速增长,从游戏娱乐到移动办公的各式各样的手机APP软件渗透到我们的生活中,对于大型的手机APP测试不仅要关注它的功能性.易用性还要关注它的性能,最近发现LoadRunner12可 ...

  7. Failed to read artifact descriptor for xxx:jar 的Maven项目jar包依赖配置的问题解决

    在开发的过程中,尤其是新手,我们经常遇到Maven下载依赖jar包的问题,也就是遇到“Failed to read artifact descriptor for xxx:jar”的错误. 对于这种非 ...

  8. HDU_1009_FatMouse' Trade

    FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  9. 详解Java动态代理机制(二)----cglib实现动态代理

    上篇文章的结尾我们介绍了普通的jdk实现动态代理的主要不足在于:它只能代理实现了接口的类,如果一个类没有继承于任何的接口,那么就不能代理该类,原因是我们动态生成的所有代理类都必须继承Proxy这个类, ...

  10. 《快学Scala》——控制结构和函数

    条件表达式 在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值.例如: if (x > 0) 1 else -1 上述表达式的值是1或-1,具体是哪一个取决于x ...