当前位置: 首页 > article >正文

js实现简单的【发布者-订阅者模式】

发布订阅模式是什么

发布订阅模式是一种代码的设计模式,它允许对象间进行松散耦合的通信。
发布者(Publishers)不会直接调用订阅者(Subscribers),相反,它们通过事件通道发布消息;订阅者通过注册监听事件通道上的消息来做出响应。
这种模式在事件驱动编程和异步编程中非常有用。

发布订阅模式怎么实现

发布订阅模式在前端开发中有广泛的应用。例如,事件处理、状态管理库(如 Redux)、消息中间件、数据流控制等

1)一个用于存储事件及其对应回调的事件中心。

2)一个 on 方法,用于订阅某个事件,并将回调函数注册到事件中心中。

3)一个 emit 方法,用于发布某个事件,并调用所有订阅该事件的回调函数。

4)一个 off 方法,用于解除订阅。

使用场景:
发布-订阅模式可用于解耦复杂的代码逻辑,例如:
浏览器中的事件处理(如点击,输入等);
背景任务和前台任务之间的通信;
多模块或组件之间的通信。

高级实现:
在实际开发中,我们可能会用到一些更复杂的发布-订阅库比如 EventEmitter (Node.js 内置)、PubSubJS 等,这些库提供了更具备鲁棒性的实现和更多特性。

代码

let eventEmitter ={
  //事件中心
  events:{},
  //订阅事件
  on: function (eventName,callback)
  {
      //如果事件不存在
      if(!this.events[eventName])
      {
        this.events[eventName] = [];
      }

      this.events[eventName].push(callback);
  },
  //发布事件 事件触发
  emit:function (eventName,...args)
  {
    // 事件不存在
    if(!this.events[eventName])
    {
      return ;
    }
    
    this.events[eventName].forEach(callback =>{
      callback(...args)
    })
  },
  //取消事件
  off:function (eventName,callback)
  {
    if(this.events[eventName])
    {
      this.events[eventName] = this.events[eventName].filter(e=>e!==callback)
    }
  },
  /**
   * 这里的 args 并没有在 once 函数的参数列表中明确声明,
   * 而是作为 onceWrapper 函数的一个内部变量(通过剩余参数语法捕获)。
   * 这是因为 onceWrapper 函数不知道它会接收多少个参数,
   * 所以它使用 ...args 来捕获所有参数,并将它们作为一个数组处理
   * 。然后,它可以通过 callback(...args) 将这些参数传递给 callback 函数
   */
  //一次性订阅
  once:function (eventName,callback)
  {
    const onceWrapper = (...args)=>{
      callback(...args)
      //执行一次后取消订阅
      this.off(eventName,onceWrapper)
    }
    this.on(eventName,onceWrapper)
  }

}

//示例
//用户定义的回调函数
function user1(msg){
  console.log("user1 ",msg);
}

function user2(msg){
  console.log("user2 ",msg);
}

function user3(msg){
  console.log("user3 ",msg);
  
}
//注册事件
eventEmitter.on("test",user1)
eventEmitter.on("test",user2)

//事件触发
eventEmitter.emit("test","这是一个测试")

//取消订阅
eventEmitter.off('test', user1);

// 发布
eventEmitter.emit('test', '这次只有 User2 收到消息');

//一次性订阅注册
eventEmitter.once("once",user3)

//事件触发两次
eventEmitter.emit("once","test by user3")
eventEmitter.emit("once","test by user3")//没有输出

http://www.kler.cn/news/351079.html

相关文章:

  • 【功能安全】系统架构设计
  • 计算机毕业设计hadoop+spark知识图谱中药推荐系统 中药材推荐系统 中药可视化 中药数据分析 中药爬虫 机器学习 深度学习 人工智能 大数据
  • 一个基于vue功能强大的表格组件--vxe-table的二次封装
  • SQL高级查询03
  • 快速搭建SpringBoot3+Prometheus+Grafana
  • Java函数式DoubleBinaryOperator接口介绍、应用场景和示例代码
  • 《C++中栈的实现:探索高效数据结构》
  • python项目实战——下载美女图片
  • golang生成并分析cpu prof文件
  • LeetCode:LCP77.符文储备(排序 Java)
  • 《Windows PE》6.4.2 远程注入DLL
  • MySQL联合索引中不同区分度列的顺序对查询性能的影响
  • Spring Boot知识管理系统:敏捷开发实践
  • Spring Boot 自动配置与 Starter POMs 深度解析
  • Excel:Cells(Rows.Count, 1).End(xlUp).Row和Cells(Rows.Count, 1).End(xlUp)有什么区别
  • Git 查看当前分支是基于哪个分支拉取(源头分支)
  • 产品开发历程|共享空间系统小程序界面风格切换
  • 开放式蓝牙耳机哪个品牌好用?开放式耳机排行榜测评!
  • 转型AI产品经理需要掌握的硬知识(三):2B和2C类AI产品公司脑洞
  • JVM篇(运行时数据区(实战课程学习总结)
  • Windows:在WPS或者Word中添加Latex公式编辑器
  • 记录Centos7 漫漫配置路
  • Apache Doris介绍
  • 物联网的应用以及优势
  • webpack和vite的区别?
  • 实时语音转文字(基于NAudio+Whisper+VOSP+Websocket)