首页 web前端 js教程 跟我学Nodejs(二)-Node.js事件模块

跟我学Nodejs(二)-Node.js事件模块

Apr 01, 2017 pm 03:57 PM
nodejs

    events是node.js 最重要的模块,events模块只提供了一个对象events.EventEmitter,EventEmitter 的核心是事件发射与事件监听器。

    Node.js中大部分的模块,都继承自Event模块。

    与DOM树上事件不同,不存在事件冒泡、逐层捕获等行为

    EventEmitter 支持若干个事件监听器。当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。   

   如何访问:

 代码如下:

1

require('events');

登录后复制

emitter.on(event, listener)

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/*

    调用events模块,获取events.EventEmitter对象

*/

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

/*

    EventEmitter.on(event, listener) 为事件注册一个监听

    参数1:event  字符串,事件名

    参数2:回调函数

*/

ee.on('some_events', function(foo, bar) {

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

});

console.log('第一轮');

ee.emit('some_events', 'Wilson', 'Zhong');

console.log('第二轮');

ee.emit('some_events', 'Wilson', 'Z');

EventEmitter.on(event, listener) 示例源码

登录后复制

emitter.emit(event, [arg1], [arg2], [...])

跟我学Nodejs(二)-Node.js事件模块


代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

ee.on('some_events', function(foo, bar) {        

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

});

/*

    EventEmitter.emit(event, [arg1], [arg2], [...])   触发指定事件

    参数1:event  字符串,事件名

    参数2:可选参数,按顺序传入回调函数的参数

    返回值:该事件是否有监听

*/

var isSuccess = ee.emit('some_events', 'Wilson', 'Zhong');

ee.on('some_events', function(foo, bar) {        

    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );

});

ee.emit('some_events', 'zhong', 'wei');

var isSuccess2 = ee.emit('other_events', 'Wilson', 'Zhong');

console.log(isSuccess);

console.log(isSuccess2);

emitter.emit(event, [arg1], [arg2], [...]) 示例源码

登录后复制

示例进行了三次触发事件操作,其中some_events注册了监听,调用时emit函数会返回一个true,而other_events并没有注册监听,emit函数会返回一个false,表示该事件没有监听;当然也可以不用管这个返回值!

emitter.once(event, listener)

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

/*

    EventEmitter.once(event, listener)  为事件注册一次性监听,触发一次后移除监听

    参数1:event  字符串,事件名

    参数2:回调函数

*/

ee.once('some_events', function(foo, bar) {

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

});

console.log('第一轮');

ee.emit('some_events', 'Wilson', 'Zhong');

console.log('第二轮');

var isSuccess =  ee.emit('some_events', 'Wilson', 'Zhong');

console.log(isSuccess);

emitter.once(event, listener) 示例源码

登录后复制

从上面示例代码执行结果可以看出,用emitter.once给some_events注册一个监听后,分两轮调用emitter.emit触发,第二轮会返回false;这表示用emitter.once注册监听和用前面讲的emitter.on注册监听略有不同,

emitter.once注册监听是一次性监听,当触发一次后,会移除该监听!当然,从名字上就看就比较明显了^_^!

emitter.removeListener(event, listener)

先来看一个失败的场景~~~

跟我学Nodejs(二)-Node.js事件模块


代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

ee.on('some_events', function(foo, bar) {

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

});

/*

    看到API中removeListener移除方法时,以为应该是这样

    但是结果^_^!!!!!

*/

ee.removeListener('some_events', function(){

    console.log('成功移除事件some_events监听!');       

});

console.log('第一轮');

ee.emit('some_events', 'Wilson', 'Zhong');

emitter.removeListener(event, listener) 示例失败场景源码

登录后复制

当我用emitter.on给some_events注册了一个监听后,我用emiiter.removeListener移除some_events的监听,随后再调用emitter.emit去触发,最后发现不是按我想像的在进行!为什么呢?

我理所当然的认为emiiter.removeListener第二个参数是个回调函数,API还是要认真看清楚啊!!!

下面再看个成功的场景~~~

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

var listener = function(foo,bar)

{

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

}

var listener2= function(foo,bar)

{

    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );

}

var listener3= function(foo,bar)

{

    console.log("第3个监听事件,参数foo=" + foo + ",bar="+bar );

}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('some_events', listener3);

/*

    EventEmitter.removeListener(event, listener)  移除指定事件的监听器

    注意:该监听器必须是注册过的

    PS:上一个例子之后以会失败,很大原因就是忽略了监听器,理所当然的认为传个事件名就OK了,所以就悲剧了!

*/

ee.removeListener('some_events', listener);

ee.removeListener('some_events', listener3);

ee.emit('some_events', 'Wilson', 'Zhong');

emitter.removeListener(event, listener) 示例成功场景源码

登录后复制

我用示例中写法,给some_events添加了三个监听,又移除了第一个和第三个监听,最后再用emitter.emit触发some_events,输出结果不难发现,用emitter.removeListener移除的第一个和第三个监听都没有再起作用,

想当然是害人地,原来emitter.removeListener的第二个参数是要移除的监听,而非移除成功后的回调函数……^_^!

emitter.removeAllListeners([event])

emitter.removeListener用过了,但一个事件可以有多个监听,需要全部移除时,一个个移除明显不是愉快的做法,不符合偷懒的天性!

让我们来体验一下emitter.removeAllListeners带来的便捷!

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

var listener = function(foo,bar)

{

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

}

var listener2= function(foo,bar)

{

    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );

}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('other_events',function(foo,bar)

{

    console.log("其它监听事件,参数foo=" + foo + ",bar="+bar );

});

/*

    EventEmitter.removeAllListeners([event])   移除(批定事件)所有监听器

    参数1:可选参数,event  字符串,事件名

*/

ee.removeAllListeners('some_events');

ee.emit('some_events', 'Wilson', 'Zhong');

ee.emit('other_events', 'Wilson', 'Zhong');

emitter.removeAllListeners 传入事件名参数示例源码

登录后复制

看看上面的执行结果,你会发现给some_events注册了两个监听;给other_events注册了一个监听;我调用emitter.removeAllListeners传了some_events事件名;

最后使用emitter.on函数触发some_events和other_events两个事件,最后发现some_events注册的两个监听都不存在,而other_events注册的监听还存在;

这表示当 emitter.removeAllListeners传用事件名作为参数时,为移除传入事件名的所有监听,而不会影响其它事件监听!

emitter.removeAllListeners可以不传用事件名参数;直接执行

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

var listener = function(foo,bar)

{

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

}

var listener2= function(foo,bar)

{

    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );

}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('other_events',function(foo,bar)

{

    console.log("其它监听事件,参数foo=" + foo + ",bar="+bar );

});

/*

    EventEmitter.removeAllListeners([event])   移除(批定事件)所有监听器

    参数1:可选参数,event  字符串,事件名

*/

ee.removeAllListeners();

ee.emit('some_events', 'Wilson', 'Zhong');

ee.emit('other_events', 'Wilson', 'Zhong');

emitter.removeAllListeners 不传参数示例源码

登录后复制

示例代码和传入参数时几乎一样,只是在调用emitter.removeAllListeners并没有传入指定事件名;

运行结果会发现some_events和other_events所有监听都不存在了,它会移除所有监听!(比较暴力的方法一般要慎用~~)

emitter.listeners(event)

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

var listener = function(foo,bar)

{

    console.log("第1个监听事件,参数foo=" + foo + ",bar="+bar );

}

var listener2= function(foo,bar)

{

    console.log("第2个监听事件,参数foo=" + foo + ",bar="+bar );

}

ee.on('some_events', listener);

ee.on('some_events', listener2);

ee.on('other_events',function(foo,bar)

{

    console.log("其它监听事件,参数foo=" + foo + ",bar="+bar );

});

/*

    EventEmitter.listeners(event)   //返回指定事件的监听数组

    参数1:event  字符串,事件名   

*/

var listenerEventsArr = ee.listeners('some_events');

console.log(listenerEventsArr.length)

for (var i = listenerEventsArr.length - 1; i >= 0; i--) {

    console.log(listenerEventsArr[i]);

};

emitter.listeners(event) 示例源码

登录后复制

给some_events注册两个监听,调用emitter.listeners函数,传入some_events事件名,接收函数返回值;

从结果可以看出,返回值接收到some_events所有注册监听的集合!

emitter.setMaxListeners(n)

一个事件可以添加多个监听是没错,但Nodejs默认最大值是多少呢?

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

/*

     给EventEmitter 添加11个监听

*/

for (var i = 10; i >= 0; i--) {

    ee.on('some_events',function()

    {

        console.log('第'+ (i +1) +'个监听');

    });

};

登录后复制

添加N个监听示例源码

上面示例中我用个循环给some_events添加11个监听,执行代码,发现warning信息出现,并且提示的比较详细了,需要用emitter.setMaxListeners()去提升限值

跟我学Nodejs(二)-Node.js事件模块

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

var EventEmitter = require('events').EventEmitter;  

var ee = new EventEmitter();

/*

    EventEmitter.setMaxListeners (n)   给EventEmitter设置最大监听

    参数1: n 数字类型,最大监听数

    超过10个监听时,不设置EventEmitter的最大监听数会提示:

    (node) warning: possible EventEmitter memory leak detected. 11 listeners added.

     Use emitter.setMaxListeners() to increase limit.

    设计者认为侦听器太多,可能导致内存泄漏,所以存在这样一个警告

*/

ee.setMaxListeners(15);

/*

     给EventEmitter 添加11个监听

*/

for (var i = 10; i >= 0; i--) {

    ee.on('some_events',function()

    {

        console.log('第'+ (i +1) +'个监听');

    });

};

emitter.setMaxListeners 示例源码

登录后复制

    当我调用emitter.setMaxListeners传入15时,执行代码,warning信息不再出现;

    emitter.setMaxListeners的作用是给EventEmitter设置最大监听数,感觉一般是不需要设置这个值,10个还不够用的情况应该是比较少了!

    设计者认为侦听器太多会导致内存泄漏,所有就给出了一个警告!

其它...

 用的比较少的就不详细说了

EventEmitter.defaultMaxListeners

    EventEmitter.defaultMaxListeners功能与setMaxListeners类似,
    给所有EventEmitter设置最大监听
    setMaxListeners优先级大于defaultMaxListeners

EventEmitter.listenerCount(emitter, event)

    返回指定事件的监听数

 特殊的事件Error

    引用自Node.js开发指南:EventEmitter 定义了一个特殊的事件 error,它包含了“错误”的语义,我们在遇到 异常的时候通常会发射 error 事件。当 error 被发射时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并打印调用栈。我们一般要为会发射 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。

事件的继承

 以上就是跟我学Nodejs(二)-Node.js事件模块的内容,更多相关内容请关注PHP中文网(www.php.cn)!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

nodejs和tomcat区别 nodejs和tomcat区别 Apr 21, 2024 am 04:16 AM

Node.js和Tomcat的主要区别在于:运行时:Node.js基于JavaScript运行时,而Tomcat是Java Servlet容器。I/O模型:Node.js采用异步非阻塞模型,而Tomcat是同步阻塞的。并发处理:Node.js通过事件循环处理并发,而Tomcat使用线程池。应用场景:Node.js适用于实时、数据密集型和高并发应用程序,Tomcat适用于传统Java Web应用程序。

nodejs和vuejs区别 nodejs和vuejs区别 Apr 21, 2024 am 04:17 AM

Node.js 是一种服务器端 JavaScript 运行时,而 Vue.js 是一个客户端 JavaScript 框架,用于创建交互式用户界面。Node.js 用于服务器端开发,如后端服务 API 开发和数据处理,而 Vue.js 用于客户端开发,如单页面应用程序和响应式用户界面。

nodejs是后端框架吗 nodejs是后端框架吗 Apr 21, 2024 am 05:09 AM

Node.js 可作为后端框架使用,因为它提供高性能、可扩展性、跨平台支持、丰富的生态系统和易于开发等功能。

nodejs安装目录里的npm与npm.cmd文件有什么区别 nodejs安装目录里的npm与npm.cmd文件有什么区别 Apr 21, 2024 am 05:18 AM

Node.js 安装目录中有两个与 npm 相关的文件:npm 和 npm.cmd,区别如下:扩展名不同:npm 是可执行文件,npm.cmd 是命令窗口快捷方式。Windows 用户:npm.cmd 可以在命令提示符下使用,npm 只能从命令行运行。兼容性:npm.cmd 特定于 Windows 系统,npm 跨平台可用。使用建议:Windows 用户使用 npm.cmd,其他操作系统使用 npm。

nodejs是后端开发语言吗 nodejs是后端开发语言吗 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一种后端开发语言。它用于后端开发,包括处理服务器端业务逻辑、管理数据库连接和提供 API。

nodejs中的全局变量有哪些 nodejs中的全局变量有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全局变量:全局对象:global核心模块:process、console、require运行时环境变量:__dirname、__filename、__line、__column常量:undefined、null、NaN、Infinity、-Infinity

nodejs和java的差别大吗 nodejs和java的差别大吗 Apr 21, 2024 am 06:12 AM

Node.js 和 Java 的主要差异在于设计和特性:事件驱动与线程驱动:Node.js 基于事件驱动,Java 基于线程驱动。单线程与多线程:Node.js 使用单线程事件循环,Java 使用多线程架构。运行时环境:Node.js 在 V8 JavaScript 引擎上运行,而 Java 在 JVM 上运行。语法:Node.js 使用 JavaScript 语法,而 Java 使用 Java 语法。用途:Node.js 适用于 I/O 密集型任务,而 Java 适用于大型企业应用程序。

nodejs项目怎么部署到服务器 nodejs项目怎么部署到服务器 Apr 21, 2024 am 04:40 AM

Node.js 项目的服务器部署步骤:准备部署环境:获取服务器访问权限、安装 Node.js、设置 Git 存储库。构建应用程序:使用 npm run build 生成可部署代码和依赖项。上传代码到服务器:通过 Git 或文件传输协议。安装依赖项:SSH 登录服务器并使用 npm install 安装应用程序依赖项。启动应用程序:使用 node index.js 等命令启动应用程序,或使用 pm2 等进程管理器。配置反向代理(可选):使用 Nginx 或 Apache 等反向代理路由流量到应用程

See all articles