Nodejs核心模块之Events

news2024/7/6 20:06:12

核心模块之Events

通过EventEmitter类实现事件统一管理

events与EventEmitter

  • node.js是基于事件驱动的异步操作架构,内置events模块
  • events模块提供了EventEmitter类
  • node.js中很多内置核心模块集成EventEmitter

EventEmitter常见Api

  • on
    • 添加实现被触发时调用的回调函数
const EventEmitter = require('events')
const ev = new EventEmitter()
// on 
ev.on('事件1', () => {
  console.log('事件1执行了---2')
})
ev.on('事件1', () => {
  console.log('事件1执行了')
})
  • emit
    • 出发事件,按照注册的顺序同步调用每个事件监听器
// emit触发
ev.emit('事件1')
  • once
    • 添加当事件在注册之后首次被触发时调用的回调函数
ev.once('事件1', () => {
  console.log('事件1执行了')
})
ev.once('事件1', () => {
  console.log('事件1执行了--2')
})

ev.emit('事件1')
ev.emit('事件1')
  • off
    • 移除特定的监听器
let cbFn = (...args) => {
  console.log(args)
}
ev.on('事件1', cbFn) 
ev.emit('事件1')
// 移除
ev.off('事件1', cbFn)
ev.emit('事件1', 1, 2, 3)

发布订阅

  • 缓存队列,存放订阅者消息
  • 具有增加和删除订阅的能力
  • 状态改变时通知所有订阅者执行监听
  • 发布订阅存在一个调度中心,而观察者中是不存在的
  • 状态发生改变时,发布订阅无须主动通知订阅者
    在这里插入图片描述
class PubSub{
  constructor() {
    this._events = {}
  }

  // 注册
  subscribe(event, callback) {
    if (this._events[event]) {
      // 如果当前 event 存在,所以我们只需要往后添加当前次监听操作
      this._events[event].push(callback)
    } else {
      // 之前没有订阅过此事件
      this._events[event] = [callback]
    }
  }

  // 发布
  publish(event, ...args) {
    const items = this._events[event]
    if (items && items.length) {
      items.forEach(function (callback) {
        callback.call(this, ...args)
      })
    }
  }
}

let ps = new PubSub()
ps.subscribe('事件1', () => {
  console.log('事件1执行了')
})
ps.subscribe('事件1', () => {
  console.log('事件1执行了---2')
})

ps.publish('事件1')
ps.publish('事件1')

EventEmitter模拟

function MyEvent () {
  // 准备一个数据结构用于缓存订阅者信息
  this._events = Object.create(null)
}

MyEvent.prototype.on = function (type, callback) {
  // 判断当前次的事件是否已经存在,然后再决定如何做缓存
  if (this._events[type]) {
    this._events[type].push(callback)
  } else {
    this._events[type] = [callback]
  }
}

MyEvent.prototype.emit = function (type, ...args) {
  if (this._events && this._events[type].length) {
    this._events[type].forEach((callback) => {
      callback.call(this, ...args)
    })
  }
}

MyEvent.prototype.off = function (type, callback) {
  // 判断当前 type 事件监听是否存在,如果存在则取消指定的监听
  if (this._events && this._events[type]) {
    this._events[type] = this._events[type].filter((item) => {
      return item !== callback && item.link !== callback
    })
  }
}

MyEvent.prototype.once = function (type, callback) {
  let foo = function (...args) {
    callback.call(this, ...args)
    this.off(type, foo)
  }
  foo.link = callback
  this.on(type, foo)
}

let ev = new MyEvent()

let fn = function (...data) {
  console.log('事件1执行了', data)
}

ev.once('事件1', fn)
// ev.off('事件1', fn)
ev.emit('事件1', '前')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/28616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学生静态HTML个人博客主页【Web大学生网页作业成品】HTML+CSS+JavaScript

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

【没用的小知识又增加了--CCS】

1.CCS中导入工程时提示overlaps the location of another project问题 ​ ​ 工作区要选择最外面的文件夹 ​ 2. error #131: expected a "{" error: #130: expected a "{"_kuyoungest的博客-CSDN博客如果该提示定位到文件开头的语句,则应在…

【Spring(四)】Spring基于注解的配置方式

有关Spring的所有文章都收录于我的专栏:👉Spring👈 目录 一、前言 二、基于注解需要的依赖 三、通过注解来配置Bean 四、注解配置Bean再补充 五、基于注解的自动装配 六、泛型依赖注入 相关文章 【Spring(一)】如何获取…

企业知识管理难?选对系统可解决90%的问题

编者按:知识管理是企业加强竞争优势和核心竞争力的保证。本文分析了企业知识管理中遇到的困难,并进一步提出了解决方案——天翎KMS群晖云盘一体机。 关键词:在线预览,在线编辑,权限管理,水印设置&#xff…

macOS Ventura13.0.1解决office缺少“宋体”等问题。安装微软雅黑、宋体等字体。

最近在弄项目验收文档,文档格式要求宋体,用微软的Word打开文件保存时经常提示,系统不存在宋体字体,查了下是是Mac系统本身不存在该字体导致的,下载该字体,然后通过字体册安装就行。 我打包成压缩包了具体有…

【易错小点记录】坑人的for循环与逻辑或

目录 1.题目 1.1.以下for循环的执行次数是( ) 1.1.1.题目分析 1.1.2.题目答案 1.2.下列main()函数执行后的结果为() 1.2.题目分析 1.3.题目答案 2.题目 2.1.下面程序输出是什么?( ) 2.…

非线性海洋捕食者算法(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜…

树表的查找

二叉排序树 二叉排序树(BST)又称二叉搜索树,其满足以下性质: (1)若根节点的左子树非空,则左子树上的所有节点关键字均小于根节点的关键字。 (2)若根节点的右子树非空&a…

补充(二)古典密码两张思维导图速通

目录 目录 古典密码思维导图 古典密码分析思维导图 唯密文分析古典密码 单表代替密码 棋盘密码 曾公密码 置换密码的代表:斯巴达人的密码棒 古典密码思维导图 古典密码分析思维导图 唯密文分析古典密码 最困难的分析条件通常需要用到英文字母的频率分析和反…

【微服务】SpringCloud中Ribbon集成Eureka实现负载均衡

💖 Spring家族及微服务系列文章 ✨【微服务】SpringCloud轮询拉取注册表及服务发现源码解析 ✨【微服务】SpringCloud微服务续约源码解析 ✨【微服务】SpringCloud微服务注册源码解析 ✨【微服务】Nacos2.x服务发现?RPC调用?重试机制&#xf…

Maven打Jar包,启动报NoClassDefFoundError错误

今天准备将游戏服务器的压测机器人打包分发给其他人来运行对服务器进行压力测试。打成的jar包发现运行报错了。找了半天才找到最终原因。下面是原因和一些分析的情况。 原因 java -jar .\robot.jar发现错误如下 看到这个错误就知道jvm找不到对应的类。但是为什么找不到对应的…

JVM的内存区域划分

文章目录 前言一、本地方法栈(线程私有)二、程序计数器(线程私有)三、Java虚拟机栈(线程私有)四、堆(线程共享)五、方法区(元数据区)前言 JVM 是Java 运行的基…

Android:Navigation使用safe args插件传递参数

Navigation使用safe args插件传递参数1、 使用配置2、举例说明1、MainActivity2、AvalFragment, DovomFragment2.1、AvalFragment2.2、DovomFragment参考1、 使用配置 afe args与传统传参方式相比,好处在于安全的参数类型,并且通过谷歌官方的支持&#…

GameFrameWork框架(Unity3D)使用笔记(六)游戏主流程ProcedureMain——从数据表加载出所需实体

目录 前言: 一、Entity配置表 1、创建数据表 2、创建数据表行类 二、Character配置表 1、创建数据表 2、写数据表行类 三、加载数据表 四、扩展一下Entity模块 五、应用Character数据表的位置信息 六、测试 总结: 前言: 上一篇中我…

第2章 Elasticsearch入门

2.1 Elasticsearch 安装 2 . 1 .1 下载软件 Elasticsearch的官方地址:www.elastic.co/cn/ Elasticsearch最新的版本是7.11.2(截止2021.3.10),我们选择7.8.0版本(最新版本半年前的版本) 下载地址&#x…

贝叶斯网络

贝叶斯网络的独立性: 当一个结点G的父节点已知的时候,该结点G与其所有非后代结点条件独立 交叉因果推断:如上述图中的例子,对于P(i | g | d)等于说是中D到I 这条路径中,做半边的路径是顺着箭头走的&#x…

表白墙(前端+后端+数据库)

目录 一、创建项目 1、创建maven项目,引入依赖 2、创建目录结构 二、前端代码 1、页面内容和样式 2、提交按钮的点击事件 3、发送GET请求 三、数据库 四、后端代码 1、重写doPost方法 1.1 创建Message类 1.2 重写doPost方法 1.3 实现save方法 2、重写…

你需要知道的50颗卫星:地球卫星清单

开放数据卫星 1陆地卫星 地球资源卫星令人难以置信的长期遗产已经保存了地球40多年的历史。通过无数的应用程序,它甚至发现 island Landsat in Canada。 图片来源:NASA 2哨兵 作为 Copernicus Programme 哨兵的6个任务的舰队是一个游戏改变者。明确地…

2022年经典散文:滚烫的石板

滚烫的石板 ——灵遁者 此刻,我想表达的情愫大概有千万种,如何表达并不容易,就好像一个人的时候,也在面对某个我认识或者不认识的人,话总是说不清,也说不出来。 小孩总是敢于表达的,就像一条没…

.NET 7 的 AOT 到底能不能扛反编译?

一:背景 1.讲故事 在B站,公众号上发了一篇 AOT 的文章后,没想到反响还是挺大的,都称赞这个东西能抗反编译,可以让破解难度极大提高,可能有很多朋友对逆向不了解,以为用 ILSpy,Reflector,DnSpy…