node.js学习之事件模块Events的使用示例


Posted in Javascript onSeptember 28, 2017

前言

本文主要给大家介绍了关于node.js事件模块Events使用的一些示例,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

环境:Node v8.2.1; Npm v5.3.0; OS Windows10

1、 Node事件介绍

Node大多数核心 API 都采用惯用的异步事件驱动架构,其中某些类型的对象(触发器)会周期性地触发命名事件来调用函数对象(监听器)。

所有能触发事件的对象都是 EventEmitter 类的实例。 这些对象开放了一个 eventEmitter.on() 函数,允许将一个或多个函数绑定到会被对象触发的命名事件上。 事件名称通常是驼峰式的字符串,但也可以使用任何有效的 JavaScript 属性名。

当 EventEmitter 对象触发一个事件时,所有绑定在该事件上的函数都被同步地调用。 监听器的返回值会被丢弃。

2、events 模块API介绍

node.js学习之事件模块Events的使用示例

3、 一些例子

下面是一些简单的例子,对应上面的API的一个代码实现

3.1 绑定和触发事件

const EventEmitter = require('events');

//自定义一个对象继承于EventEmitter
class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter();

myEmitter.on('event', () => {
 console.log('触发了一个事件!');
});

myEmitter.emit('event');

3.2 为事件传递参数

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('event', (a,b) => {
 console.log(a,b);
 //1,2
}); 
myEmitter.emit('event','a','b');

3.3 this 的问题

当一个普通的监听器函数被 EventEmitter 调用时,标准的 this 关键词会被设置指向监听器所附加的 EventEmitter。

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('event', function() {
 console.log(this);
 /*
  a b MyEmitter {
   domain: null,
   _events: { event: [Function] },
   _eventsCount: 1,
   _maxListeners: undefined 
  }
 */
 }); 
myEmitter.emit('event');

也可以使用 ES6 的箭头函数作为监听器。但是这样 this 关键词就不再指向 EventEmitter 实例:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('event', () => {
 console.log(this);
 //{}
});

myEmitter.emit('event');

3.4 异步执行

EventListener 会按照监听器注册的顺序同步地调用所有监听器,监听器函数可以使用 setImmediate()process.nextTick() 方法切换到异步操作模式:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

myEmitter.on('event', (a,b) => {
 setImmediate(()=>{
  //异步触发
  console.log(a,b);
 })
 console.log("c");
});

myEmitter.emit('event','a','b');
//c
//a b

3.5 无限次触发和一次触发

事件默认是可以无限次数的触发的,只要触发一次,对应的监听函数就执行一次;有时候我们希望只执行一次监听函数,可以使用【once】对事件进行绑定

多次触发:

const EventEmitter = require('events')

class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter();

let m = 0;

myEmitter.on('event', () => {
 console.log(++m);
});

myEmitter.emit('event'); //1

myEmitter.emit('event'); //2

myEmitter.emit('event'); //3

一次触发:

const EventEmitter = require('events')

class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter();

let m = 0;

myEmitter.once('event', () => {
 console.log(++m);
});

myEmitter.emit('event'); //1

myEmitter.emit('event'); //忽略

myEmitter.emit('event'); //忽略

3.6 错误事件

当 EventEmitter 实例中发生错误时,会触发一个 ‘error' 事件,如果 EventEmitter 没有为 ‘error' 事件注册至少一个监听器,则当 ‘error' 事件触发时,会抛出错误、打印堆栈跟踪、且退出 Node.js 进程。

const EventEmitter = require('events');

class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter();

myEmitter.emit("error", new Error('whoops!'));
// 抛出错误,并使 Node.js 崩溃

为了防止 Node.js 进程崩溃,可以在 process 对象的 uncaughtException 事件上注册监听器

const EventEmitter = require('events')

class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter();
//在进程上面注册错误监听,使进程不崩溃
process.on("uncaughtException",()=>{
 console.error('有错误');
});

myEmitter.emit("error",new Error("whoops"))

上面这样的方式并不是最佳实践,最好是为【error】注册监听函数

3.7 获取和修改最大事件监听数量

Node默认一个事件的监听数量为10个,超过十个将会发出警告

const EventEmitter = require('events')

class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter();

console.log(EventEmitter.defaultMaxListeners); //10

for (let i = 0; i < 11; i++) {
 myEmitter.on("event", () => {
  console.log(i);
 });
}
myEmitter.emit("event")
//MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 event listeners added. Use emitter.setMaxListeners() to increase limit

改变指定的 EventEmitter 实例的监听器限制

const EventEmitter = require('events')

class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter();

myEmitter.setMaxListeners(13);

for (let i = 0; i < 11; i++) {
 myEmitter.on("event", () => {
  console.log(i);
 });
}
myEmitter.emit("event")

3.8 newListener事件

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

const EventEmitter = require('events')

class MyEmitter extends EventEmitter { }

const myEmitter = new MyEmitter()

myEmitter.once("newListener", (event, listener) => {
 if(event === "event"){
  myEmitter.on("event",()=>{
   console.log("B");
  })
 }
});

myEmitter.on("event",()=>{
 console.log("A");
});

myEmitter.emit("event")
/*
B
A
*/

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
几个常用的JavaScript字符串处理函数 - split()、join()、substring()和indexOf()
Jun 02 Javascript
jQuery 操作下拉列表框实现代码
Feb 22 Javascript
cookie.js 加载顺序问题怎么才有效
Jul 31 Javascript
浅谈Unicode与JavaScript的发展史
Jan 19 Javascript
Web开发必知Javascript技巧大全
Feb 23 Javascript
JavaScript通过使用onerror设置默认图像显示代替alt
Mar 01 Javascript
js对象浅拷贝和深拷贝详解
Sep 05 Javascript
移动端触屏幻灯片图片切换插件idangerous swiper.js
Apr 10 Javascript
vue2中,根据list的id进入对应的详情页并修改title方法
Aug 24 Javascript
jquery 遍历hash操作示例【基于ajax交互】
Oct 12 jQuery
关于在LayUI中使用AJAX提交巨坑记录
Oct 25 Javascript
vue解决花括号数据绑定不成功的问题
Oct 30 Javascript
es6中的解构赋值、扩展运算符和rest参数使用详解
Sep 28 #Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
Sep 28 #Javascript
jquery实现左右轮播图效果
Sep 28 #jQuery
bootstrap table实现点击翻页功能 可记录上下页选中的行
Sep 28 #Javascript
JavaScript判断输入是否为数字类型的方法总结
Sep 28 #Javascript
详解Node全局变量global模块
Sep 28 #Javascript
React Native预设占位placeholder的使用
Sep 28 #Javascript
You might like
收音机另类DIY - 纸巾盒做外壳
2021/03/02 无线电
php提示Failed to write session data错误的解决方法
2014/12/17 PHP
php读取torrent种子文件内容的方法(测试可用)
2016/05/03 PHP
PHP使用HTML5 FormData对象提交表单操作示例
2019/07/02 PHP
引用 js在IE与FF之间的区别详细解析
2013/11/20 Javascript
jquery中EasyUI实现同步树
2015/03/01 Javascript
Bootstrap Modal对话框如何在关闭时触发事件
2016/12/02 Javascript
JS百度地图搜索悬浮窗功能
2017/01/12 Javascript
AngularJS中使用ngModal模态框实例
2017/05/27 Javascript
vue-router路由参数刷新消失的问题解决方法
2017/06/17 Javascript
基于twbsPagination.js分页插件使用心得(分享)
2017/10/21 Javascript
vue的传参方式汇总和router使用技巧
2018/05/22 Javascript
vue计算属性get和set用法示例
2019/02/08 Javascript
layui监听下拉选框选中值变化的方法(包含监听普通下拉选框)
2019/09/24 Javascript
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
2020/12/14 NodeJs
使用Python3编写抓取网页和只抓网页图片的脚本
2015/08/20 Python
深入解析Python中的变量和赋值运算符
2015/10/12 Python
Python实现使用卷积提取图片轮廓功能示例
2018/05/12 Python
Sanic框架路由用法实例分析
2018/07/16 Python
opencv python 2D直方图的示例代码
2018/07/20 Python
Pytorch修改ResNet模型全连接层进行直接训练实例
2019/09/10 Python
Python中filter与lambda的结合使用详解
2019/12/24 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
2020/03/09 Python
python自动下载图片的方法示例
2020/03/25 Python
Python实现曲线拟合的最小二乘法
2021/02/19 Python
美国婴儿用品店:Babies”R”Us
2017/10/12 全球购物
医学类导师推荐信范文
2013/11/19 职场文书
保荐人的岗位职责
2013/11/19 职场文书
小学语文教学反思
2014/02/10 职场文书
财务管理专业求职信
2014/06/11 职场文书
稽核岗位职责范本
2015/04/13 职场文书
2015年法律事务部工作总结
2015/07/27 职场文书
导游词之丽江普济寺
2019/10/22 职场文书
Python Numpy之linspace用法说明
2021/04/17 Python
《帝国时代4》赛季预告 新增内容编译器可创造地图
2022/04/03 其他游戏
maven 解包依赖项中的文件的解决方法
2022/07/15 Java/Android