一、EventEmitter 类

  Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列

  Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一个fs.readStream对象会在文件被打开的时候发出一个事件。 所有这些产生事件的对象都是 events.EventEmitter 的实例。

  events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装。你可以通过require("events");来访问该模块。

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

  EventEmitter 对象如果在实例化时发生错误,会触发 error 事件。当添加新的监听器时,newListener 事件会触发,当监听器被移除时,removeListener 事件被触发。下面我们用一个简单的例子说明 EventEmitter 的用法:

//event.js 文件
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter();
event.on('some_event', function() {
console.log('some_event 事件触发');
});
setTimeout(function() {
event.emit('some_event');
}, );

  执行结果如下:运行这段代码,$ node event.js , 事件触发1 秒后控制台输出了 'some_event 事件触发'。其原理是 event 对象注册了事件 some_event 的一个监听器,然后我们通过 setTimeout 在 1000 毫秒以后向 event 对象发送事件 some_event,此时会调用some_event 的监听器。(看到这里应该对vue里面子组件向父组件通信有了更深的理解了,正是使用了这种机制。)

  EventEmitter 的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持若干个事件监听器。

当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。让我们以下面的例子解释这个过程:

//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
//结果如下
$ node event.js
listener1 arg1 参数 arg2 参数
listener2 arg1 参数 arg2 参数

  以上例子中,emitter 为事件 someEvent 注册了两个事件监听器,然后触发了 someEvent 事件。运行结果中可以看到两个事件监听器回调函数被先后调用。 这就是EventEmitter最简单的用法。

  EventEmitter 提供了多个属性,如 onemiton 函数用于绑定事件函数,emit 属性用于触发一个事件。

  接下来我们来具体看下 EventEmitter 的属性介绍。

addListener(event, listener)
  为指定事件添加一个监听器到监听器数组的尾部。

on(event, listener)
  为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。

once(event, listener)
  为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。

removeListener(event, listener)

  移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。它接受两个参数,第一个是事件名称,第二个是回调函数名称。

removeAllListeners([event])
  移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。

setMaxListeners(n)
  默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。
setMaxListeners 函数用于提高监听器的默认限制的数量。

listeners(event)
  返回指定事件的监听器数组。

emit(event, [arg1], [arg2], [...])
  按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false。

listenerCount(emitter, event)
  返回指定事件的监听器数量。

  事件:

newListener

  • event - 字符串,事件名称

  • listener - 处理事件函数

  该事件在添加新监听器时被触发。

removeListener

  • event - 字符串,事件名称

  • listener - 处理事件函数

  从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。

  以下实例通过 connection(连接)事件演示了 EventEmitter 类的应用。

  创建 main.js 文件,代码如下:

  eventEmitter.on()与eventEmitter.addListener()没有区别,且一个事件可以绑定多个回调函数;

var events = require('events');
var eventEmitter = new events.EventEmitter(); // 监听器 #1
var listener1 = function listener1() {
console.log('监听器 listener1 执行。');
} // 监听器 #2
var listener2 = function listener2() {
console.log('监听器 listener2 执行。');
} // 绑定 connection 事件,处理函数为 listener1
eventEmitter.addListener('connection', listener1); // 绑定 connection 事件,处理函数为 listener2
eventEmitter.on('connection', listener2); var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 个监听器监听连接事件。"); // 处理 connection 事件
eventEmitter.emit('connection'); // 移除监绑定的 listener1 函数
eventEmitter.removeListener('connection', listener1);
console.log("listener1 不再受监听。"); // 触发连接事件
eventEmitter.emit('connection'); eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 个监听器监听连接事件。"); console.log("程序执行完毕。");
//结果如下:
$ node main.js
个监听器监听连接事件。
监听器 listener1 执行。
监听器 listener2 执行。
listener1 不再受监听。
监听器 listener2 执行。
个监听器监听连接事件。
程序执行完毕。

二、error 事件

  EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到异常的时候通常会触发 error 事件。当 error 被触发时,EventEmitter 规定如果没有响应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。若事件队列中出现一个未绑定事件则触发error事件,若未绑定 error事件则程序抛出异常结束执行。我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:

var events = require('events');
var emitter = new events.EventEmitter();
emitter.emit('error');
//运行时会显示以下错误:

node.js:
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Uncaught, unspecified 'error' event.
at EventEmitter.emit (events.js::)
at Object.<anonymous> (/home/byvoid/error.js::)
at Module._compile (module.js::)
at Object..js (module.js::)
at Module.load (module.js::)
at Function._load (module.js::)
at Array. (module.js::)
at EventEmitter._tickCallback (node.js::)

三、继承 EventEmitter

  大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类

  为什么要这样做呢?原因有两点:

  首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。

  其次,JavaScript 的对象机制是基于原型的,支持部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。

Node.js:EventEmitter类的更多相关文章

  1. Node.js EventEmitter

    Node.js EventEmitter Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列. Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有 ...

  2. 7、Node.js EventEmitter

    #######################################################################################介绍Node.js Eve ...

  3. Node.js 学习(六)Node.js EventEmitter

    Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列. Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一个fs.read ...

  4. 20.Node.js EventEmitter的方法和事件

    转自:http://www.runoob.com/nodejs/nodejs-tutorial.html EventEmitter 提供了多个属性,如 on 和 emit.on 函数用于绑定事件函数, ...

  5. 19.Node.js EventEmitter

    转自:http://www.runoob.com/nodejs/nodejs-tutorial.html Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列. Node.js里 ...

  6. Node.js EventEmitter(事件队列)

    Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列. Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一个fs.read ...

  7. node.js EventEmitter发送和接收事件

    EventEmitter是nodejs核心的一部分.很多nodejs对象继承自EventEmitter,用来处理事件,及回调.api文档地址: http://nodejs.org/api/events ...

  8. node.js—Buffer类(二进制数据处理模块)

    Buffer类概述 一个用于更好的操作二进制数据的类 我们在操作文件或者网络数据的时候,其实操作的就是二进制数据流 Node为我们提供了一个更加方便的去操作这种数据流的类 Buffer,他是一个全局的 ...

  9. node(2) EventEmitter类 事件队列 事件和error事件方法

    事件队列的核心:事件触发与事件监听器功能的封装. // 引入 events 模块 var events = require('events'); // 创建 eventEmitter 对象 var e ...

  10. [Node.js] querystring类

    和参数相关的帮助类,原生自带,直接 require('querystring') 即可使用. 此类一共包括4个方法: querystring.stringify(obj, [sep], [eq]) q ...

随机推荐

  1. centos7 lamp环境搭建

    一.安装Apache1.安装yum -y install httpd2.开启apache服务systemctl start httpd.service3.设置apache服务开机启动systemctl ...

  2. ref:JAVA代码审计的一些Tips(附脚本)

    ref:https://xz.aliyun.com/t/1633/ JAVA代码审计的一些Tips(附脚本) 概述 本文重点介绍JAVA安全编码与代码审计基础知识,会以漏洞及安全编码示例的方式介绍JA ...

  3. linux网络管理----网络基础

    1.1 ISO/OSI 七层模型 笔记: 打入ipconfig: mac地址:Media Access Control 也是物理地址,这是由网卡决定的.负责的是内网,也就是局域网通信. IPv4地址: ...

  4. PHP库函数积累,持续更新

    1. gethostbyname($server_name) 作用:根据给定的域名获取对应的ip 示例:echo gethostbyname("www.baidu.com"); 2 ...

  5. [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1888  Solved: 898[Submit][Statu ...

  6. Codeforces Round #479 (Div. 3)

    手速场2333,这群人贼牛逼!手速贼快!   A. Wrong Subtraction time limit per test 1 second memory limit per test 256 m ...

  7. 【Trie图】BZOJ3940-[Usaco2015 Feb]Censoring

    [题目大意] 有一个匹配串和多个模式串,现在不断删去匹配串中的模式串,求出最后匹配串剩下的部分. [思路] 众所周知,KMP的题往往对应着一道AC自动机quq.本题同BZOJ3942(KMP),这里改 ...

  8. PHP -- 类和对象基础入门

         本文目录:    创建简单类和对象 继承 抽象类 接口 构造方法 析构函数     1. 创建简单类    创建一个People的类,在这里有四个要点说明一下: 第一个是在PHP中,访问属性 ...

  9. [转]Activity详解 Intent显式跳转和隐式跳转

    Activity 生命周期             显式 Intent 调用          1     //创建一个显式的 Intent 对象(方法一:在构造函数中指定)  2      Inte ...

  10. [转]String.Replace 和 String.ReplaceAll 的区别

    JAVA 中的 replace replaceAll 问题: 测试code System.out.println("1234567890abcdef -----> "+&qu ...