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 面向对象 function类
May 13 Javascript
动态改变div的z-index属性的简单实例
Aug 08 Javascript
JS批量操作CSS属性详细解析
Dec 16 Javascript
浅谈js图片前端预览之filereader和window.URL.createObjectURL
Jun 30 Javascript
脚本div实现拖放功能(两种)
Feb 13 Javascript
vue2.0父子组件间通信的实现方法
Apr 19 Javascript
使用 Vue.js 仿百度搜索框的实例代码
May 09 Javascript
node.js操作mongodb简单示例分享
May 25 Javascript
vue里input根据value改变背景色的实例
Sep 29 Javascript
Vue 处理表单input单行文本框的实例代码
May 09 Javascript
Egg Vue SSR 服务端渲染数据请求与asyncData
Nov 24 Javascript
VUE中V-IF条件判断改变元素的样式操作
Aug 09 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
西德产收音机
2021/03/01 无线电
phpMyAdmin 安装及问题总结
2009/05/28 PHP
php 随机数的产生、页面跳转、件读写、文件重命名、switch语句
2009/08/07 PHP
CI框架源码阅读,系统常量文件constants.php的配置
2013/02/28 PHP
php实现获取文章内容第一张图片的方法
2014/11/04 PHP
PHP反射基础知识回顾
2020/09/10 PHP
从javascript语言本身谈项目实战
2006/12/27 Javascript
js prototype截取字符串函数
2010/04/01 Javascript
js点击页面其它地方将某个显示的DIV隐藏
2012/07/12 Javascript
Js点击弹出下拉菜单效果实例
2013/08/12 Javascript
jQuery动态显示和隐藏datagrid中的某一列的方法
2013/12/11 Javascript
js插件方式打开pdf文件(浏览器pdf插件分享)
2013/12/20 Javascript
jQuery表格列宽可拖拽改变且兼容firfox
2014/09/03 Javascript
jquery实现无限分级横向导航菜单的方法
2015/03/12 Javascript
javascript实现淘宝幻灯片广告展示效果
2015/04/27 Javascript
理解javascript中的原型和原型链
2015/07/30 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
2015/12/03 Javascript
Jquery轮播效果实现过程解析
2016/03/30 Javascript
Javascript 获取鼠标当前的位置实现方法
2016/10/27 Javascript
JavaScript中双向数据绑定详解
2017/05/03 Javascript
jQuery读取本地的json文件(实例讲解)
2017/10/31 jQuery
在vue项目中,使用axios跨域处理
2018/03/07 Javascript
node 版本切换的实现
2020/02/02 Javascript
Vue关于组件化开发知识点详解
2020/05/13 Javascript
[02:28]DOTA2 2015国际邀请赛中国区预选赛首日现场百态
2015/05/26 DOTA
Python编写Windows Service服务程序
2018/01/04 Python
Python 3 实现定义跨模块的全局变量和使用教程
2019/07/07 Python
python+tifffile之tiff文件读写方式
2020/01/13 Python
Python通过format函数格式化显示值
2020/10/17 Python
css3截图_动力节点Java学院整理
2017/07/11 HTML / CSS
CSS3 选择器 伪类选择器介绍
2012/01/21 HTML / CSS
优秀员工个人的自我评价
2013/11/29 职场文书
安全生产中长期规划实施方案
2014/02/21 职场文书
2016大一新生军训感言
2015/12/08 职场文书
深入解析NumPy中的Broadcasting广播机制
2021/05/30 Python