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 相关文章推荐
node.js中的fs.close方法使用说明
Dec 17 Javascript
Jquery的基本对象转换和文档加载用法实例
Feb 25 Javascript
JS组件Bootstrap Table表格多行拖拽效果实现代码
Dec 08 Javascript
基于javascript html5实现3D翻书特效
Mar 14 Javascript
jQuery+CSS3+Html5实现弹出层效果实例代码(附源码下载)
May 16 Javascript
微信小程序 下拉菜单的实现
Apr 06 Javascript
jQuery判断邮箱格式对错实例代码讲解
Apr 12 jQuery
微信小程序实战之自定义模态弹窗(8)
Apr 18 Javascript
vue-cli2.9.3 详细教程
Apr 23 Javascript
Hexo已经看腻了,来手把手教你使用VuePress搭建个人博客
Apr 26 Javascript
vue-cli 使用vue-bus来全局控制的实例讲解
Sep 15 Javascript
node.js使用mongoose操作数据库实现购物车的增、删、改、查功能示例
Dec 23 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
有关JSON以及JSON在PHP中的应用
2010/04/09 PHP
php魔术变量用法实例详解
2014/11/13 PHP
PHP仿微信发红包领红包效果
2016/10/30 PHP
laravel获取不到session的三种解决办法【推荐】
2018/09/16 PHP
用JavaScript隐藏控件的方法
2009/09/21 Javascript
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
限制textbox或textarea输入字符长度的JS代码
2013/10/16 Javascript
当滚动条滚动到页面底部自动加载增加内容的js代码
2014/05/13 Javascript
js实现星星打分效果的方法
2020/07/05 Javascript
javascript委托(Delegate)blur和focus用法实例分析
2015/05/26 Javascript
jQuery Validate初步体验(二)
2015/12/12 Javascript
基于jquery插件编写countdown计时器
2016/06/12 Javascript
JS实现pasteHTML兼容ie,firefox,chrome的方法
2016/06/22 Javascript
vue2.0父子组件间通信的实现方法
2017/04/19 Javascript
vue中手机号,邮箱正则验证以及60s发送验证码的实例
2018/03/16 Javascript
JS中用EL表达式获取上下文参数值的方法
2018/03/28 Javascript
layer.alert回调函数执行关闭弹窗的实例
2019/09/11 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
2019/11/14 Javascript
Vue 实现分页与输入框关键字筛选功能
2020/01/02 Javascript
Vue组件跨层级获取组件操作
2020/07/27 Javascript
python简单获取本机计算机名和IP地址的方法
2015/06/03 Python
python实现接口并发测试脚本
2019/06/25 Python
django数据关系一对多、多对多模型、自关联的建立
2019/07/24 Python
通过Python编写一个简单登录功能过程解析
2019/09/04 Python
Django框架 查询Extra功能实现解析
2019/09/04 Python
python3获取url文件大小示例代码
2019/09/18 Python
在Python中字符串、列表、元组、字典之间的相互转换
2019/11/15 Python
基于css3仿造window7的开始菜单
2010/06/17 HTML / CSS
使用CSS3实现SVG路径描边动画效果入门教程
2019/10/21 HTML / CSS
ProForm英国站点:健身房和健身器材网上商店
2019/06/05 全球购物
捷克母婴用品购物网站:Feedo.cz
2020/12/28 全球购物
审计主管岗位职责
2014/01/31 职场文书
计算机专业毕业生自荐书
2014/06/02 职场文书
居委会四风问题个人对照检查材料
2014/09/25 职场文书
罚站检讨书
2015/01/29 职场文书
求职信:求职应该注意的问题
2019/04/24 职场文书