HarmonyOS Next 浅谈 发布-订阅模式

简介: 本文浅谈 HarmonyOS Next 中的发布-订阅模式,通过 ArkTS 的 Emitter 对象实现事件的持续订阅、单次订阅、取消订阅和触发功能。文章详细介绍了设计目标、接口定义及具体实现步骤,包括类型定义、类结构设计和调用示例。发布-订阅模式有助于系统解耦与扩展,适用于工具封装和游戏开发等场景。文末附有效果图和总结,帮助开发者更好地理解和应用该模式。

HarmonyOS Next 浅谈 发布-订阅模式

前言

其实在目前的鸿蒙应用开发中,或者大前端时代、vue、react、小程序等等框架、语言开发中,普通的使用者越来越少的会碰到必须要掌握设计模式的场景。大白话意思就是一些框架封装太好了,使用者只管在它们的体系下使用就行,哪怕不懂设计模式,也不妨碍我们正常开发业务。但是,如果碰到要封装一些工具、或者游戏开发的时候,那么设计模式的重要性就突显出来了。因为在做封装的时候,如果不使用一些设计模式,那么这些封装的代码基本无法使用。有同感的小伙伴可以踊跃发言。😄

image-20241120214237877

目标

arkts 中,存在 Emitter 对象,它具有持续订阅事件和单次订阅事件、取消订阅事件、触发事件的能力。我们可以将它做为封装的参考,来自己实现一个类似的封装。

Emitter 的使用就是典型的发布-订阅的设计模式。也可以理解为(生产者-消费者设计模式)

  1. 订阅 理解为我们向邮局订阅一些报刊
  2. 发布 理解为报刊发布了,我们自然会受到对应的新报刊
  3. 对于订阅者来说
    1. 我们可以无限时长的订阅报刊(持续订阅)
    2. 我们可以只订阅一次报刊(单次订阅)
    3. 可以取消订阅的报刊
  4. 对于发布者来说
    1. 负责发布即可

接口设计

方法 说明
on 持续订阅
once 单词订阅
off 取消订阅
emit 发布

具体实现

定义类型

  1. eventType 定义一个事件类型的联合类型,它可以是 normal 或者 once
  2. IEventItem 定义一个事件项的接口,包含事件 ID、类型、回调函数数组以及事件具体类型等属性
// 定义一个事件类型的联合类型,它可以是 "normal" 或者 "once"
type eventType = "normal" | "once";

// 定义一个事件项的接口,包含事件ID、类型、回调函数数组以及事件具体类型等属性
interface IEventItem {
   
  eventId: number;
  type: string;
  cbs: Function[];
  eventType: eventType;
}

定义类的基本结构

  1. MyEmitter 为封装 Emitter 的自定义类的名称
  2. listeners 存储所有事件监听器的私有静态数组,初始为空
  3. _eventId 用于生成唯一事件 ID 的私有静态变量,初始值为 0
  4. _on 私有静态方法,用于添加事件监听器 ,接受事件类型、事件名称和回调函数作为参数
  5. on 静态方法,用于添加普通类型的事件监听器
  6. once 静态方法,用于添加只触发一次的事件监听器
  7. emit 静态方法,用于触发指定类型的事件,会遍历该事件类型对应的所有回调函数并执行它们
  8. off 静态方法,用于移除指定事件 ID 的事件监听器,接受事件 ID 作为必选参数,可选地接受一个回调函数作为参数,如果只传入事件 ID,将移除该 ID 对应的整个事件项;如果同时传入回调函数,将只移除该事件项中对应的回调函数
class MyEmitter {
   
  // 存储所有事件监听器的私有静态数组,初始为空
  private static listeners: IEventItem[] = [];
  // 用于生成唯一事件ID的私有静态变量,初始值为0
  private static _eventId: number = 0;

  // 私有静态属性的getter方法,每次调用返回递增后的_eventId值
  // 用于获取下一个可用的事件ID
  private static get eventId() {
   
  }

  // 私有静态方法,用于添加事件监听器
  // 接受事件类型、事件名称和回调函数作为参数
  private static _on(eventType: eventType, type: string, cb: Function) {
   

  }

  // 静态方法,用于添加普通类型的事件监听器
  // 接受事件名称和回调函数作为参数
  // 内部调用私有静态方法 _on 并传入 "normal" 事件类型
  static on(type: string, cb: Function) {
   

  }

  // 静态方法,用于添加只触发一次的事件监听器
  // 接受事件名称和回调函数作为参数
  // 内部调用私有静态方法 _on 并传入 "once" 事件类型
  static once(type: string, cb: Function) {
   

  }

  // 静态方法,用于触发指定类型的事件
  // 接受事件名称作为必选参数,可选地接受一个数据参数
  // 会遍历该事件类型对应的所有回调函数并执行它们
  static emit<T = undefined>(type: string, data?: T) {
   

  }

  // 静态方法,用于移除指定事件ID的事件监听器
  // 接受事件ID作为必选参数,可选地接受一个回调函数作为参数
  // 如果只传入事件ID,将移除该ID对应的整个事件项;如果同时传入回调函数,将只移除该事件项中对应的回调函数
  static off(eventId: number, cb?: Function) {
   

}

调用示例

@Entry
@Component
struct Index {
   
  tid: number = -1

  build() {
   
    Column({
    space: 10 }) {
   
      Button("1 注册常规事件")
        .onClick(() => {
   
          this.tid = MyEmitter.on("login", (res: object) => {
   
            console.log(JSON.stringify(res))
          })
        })
      Button("1 取消常规事件")
        .onClick(() => {
   
          MyEmitter.off(this.tid)
        })
      Button("1 触发常规事件")
        .onClick(() => {
   
          MyEmitter.emit("login", 100)
        })
      Button("2 注册一次性事件")
        .onClick(() => {
   
          this.tid = MyEmitter.once("login2", (res: object) => {
   
            console.log(JSON.stringify(res))
          })
        })
      Button("2 取消一次性事件")
        .onClick(() => {
   
          MyEmitter.off(this.tid)
        })
      Button("2 触发一次性事件")
        .onClick(() => {
   
          MyEmitter.emit("login2", 100)
        })
      Button("3 注册具名事件")
        .onClick(() => {
   
          this.tid = MyEmitter.on("login1", this.fn1)
        })
      Button("3 取消具名事件")
        .onClick(() => {
   
          MyEmitter.off(this.tid, this.fn1)
        })
      Button("3 触发具名事件")
        .onClick(() => {
   
          MyEmitter.emit("login1", 300)
        })

    }
    .height('100%')
    .width('100%')
  }

  fn1(n: number) {
   
    console.log("具名事件", n)
  }
}

效果图

image-20241120220915524

总结

发布 - 订阅模式是一种非常有用的软件设计模式,它可以实现系统的解耦、可扩展性和灵活性。在实际应用中,需要根据具体的需求和场

景选择合适的实现方式

目录
相关文章
|
7月前
|
设计模式 存储 JavaScript
HarmonyOS Next 浅谈 发布-订阅模式
本文浅谈 HarmonyOS Next 中的发布-订阅模式,通过 ArkTS 的 Emitter 对象实现事件的订阅、发布与管理。文章介绍了设计模式在现代开发中的重要性,特别是封装工具或游戏开发时的应用。具体实现中定义了 `on`(持续订阅)、`once`(单次订阅)、`off`(取消订阅)和 `emit`(发布事件)等方法,并通过 TypeScript 实现了一个自定义的 `MyEmitter` 类。示例代码展示了如何注册、触发和取消事件,图文并茂地说明了该模式的实际效果。发布-订阅模式有助于系统解耦,提升代码的可扩展性和灵活性,适合需要高效事件管理的场景。
131 12
HarmonyOS Next 浅谈 发布-订阅模式
|
9月前
|
存储 人工智能 Serverless
AI 短剧遇上函数计算,一键搭建内容创意平台
为了帮助更多内容创作者和企业快速实现 AI 短剧创作,函数计算 FC 联合百炼联合推出“AI 剧本生成与动画创作解决方案”,通过函数计算 FC 构建 Web 服务,结合百炼模型服务和 ComfyUI 生图平台,实现从故事剧本撰写、插图设计、声音合成和字幕添加到视频合成的一站式自动化流程。创作者只需通过简单操作,就能快速生成高质量的剧本,并一键转化为精美的动画。
584 110
|
9月前
|
JavaScript 前端开发 Shell
Flow-CLI 全新升级,轻松对接 Sonar 实现代码扫描和红线卡点
Flow-CLI 使用的典型场景如:自定义开发一个 Sonar 扫描步骤,以在流水中触发 Sonar 扫描,并以扫描结果作为红线卡点,以保证代码质量;对接三方自有审批平台,在发布前进行检查审批,审批通过才允许发布。接下来,我们就以对接 Sonar 服务为例,手把手教你开发一个带红线功能的 Sonar 扫描步骤。
618 124
|
7月前
|
移动开发 JavaScript API
HarmonyOS Next 简单上手元服务开发
本文介绍了 HarmonyOS Next 中元服务的开发流程与关键特性。元服务是一种轻量级应用程序形态,支持免安装、秒开直达,适用于听音乐、打车等场景,大幅提升服务获取效率。文章详细讲解了元服务的开发旅程,包括在 AGC 平台上新建项目、修改名称与图标、新增卡片等内容,并提供了代码示例,如 AtomicServiceTabs 的 tab 切换和标题设置、AtomicServiceNavigation 的路由管理等。此外,还探讨了 AtomicServiceWeb 的使用方法,涵盖鸿蒙页面与 h5 页面的数据传递及方法调用。
445 20
HarmonyOS Next 简单上手元服务开发
|
7月前
|
开发者 容器
小白必看 HarmonyOS Next HMRouter 轻松上手秘籍
本文详细介绍了HarmonyOS页面跳转解决方案——HMRouter的使用方法,帮助开发者快速上手。HMRouter封装了系统Navigation能力,提供路由拦截、页面生命周期管理、自定义转场动画等功能,简化开发流程。文章通过具体示例讲解模块内及跨模块页面跳转、路由传参、自定义动画、拦截器和生命周期管理等核心功能。同时,提供了丰富的资源链接,包括接口文档、高级动画教程和常见问题解答,适合初学者系统学习HMRouter的使用与原理。
483 9
小白必看 HarmonyOS Next HMRouter 轻松上手秘籍
|
7月前
|
关系型数据库 BI OLAP
一招解决数据库中报表查询慢的痛点
本文旨在解决传统数据库系统如PostgreSQL在处理复杂分析查询时面临的性能瓶颈问题。
1311 163
一招解决数据库中报表查询慢的痛点
|
7月前
|
传感器 JavaScript 调度
HarmonyOS Next 并发 taskpool 和 worker
HarmonyOS Next 提供了 TaskPool 和 Worker 两种并发能力,基于 Actor 并发模型实现。TaskPool 是 Worker 的封装,支持参数直接传递、返回数据接收、任务优先级设置及取消功能,适合大多数场景;Worker 则适用于超长任务或需手动管理线程生命周期的场景。两者通过消息通信完成跨线程数据交换,支持普通对象拷贝、ArrayBuffer 拷贝/转移、SharedArrayBuffer 共享及 Sendable 引用传递等方式。实际开发中,TaskPool 更简化任务调度,而 Worker 更灵活,可根据任务类型(耗时、长时、常驻)选择合适方案。
249 12
HarmonyOS Next 并发 taskpool 和 worker
|
7月前
|
前端开发 程序员 API
鸿蒙元服务实战-笑笑五子棋(1)
《笑笑五子棋》是基于鸿蒙系统开发的元服务应用,由深度开发者分享开源。名字源于开发者女儿“笑笑”,充满程序员的独特浪漫。应用采用 ArkTS API 12、Canvas 等技术,支持 AtomicServiceTabs 和卡片开发,已成功上架并获得基础激励。凭借活跃设备数达标,还登上鸿蒙负一屏休闲分类菜单,提升了用户活跃度。本文介绍了应用背景和技术细节,下篇将聚焦代码实现。适合对鸿蒙开发感兴趣的开发者学习交流。
142 10
鸿蒙元服务实战-笑笑五子棋(1)
|
9月前
|
SQL Cloud Native API
NSDI'24 | 阿里云飞天洛神云网络论文解读——《Poseidon》揭秘新型超高性能云网络控制器
NSDI‘24于4月16-18日在美国加州圣塔克拉拉市举办,汇聚全球网络系统领域的专家。阿里云飞天洛神云网络的两篇论文入选,标志着其创新能力获广泛认可。其中,《Poseidon: A Consolidated Virtual Network Controller that Manages Millions of Tenants via Config Tree》介绍了波塞冬平台,该平台通过统一控制器架构、高性能配置计算引擎等技术,实现了对超大规模租户和设备的高效管理,显著提升了云网络性能与弹性。实验结果显示,波塞冬在启用EIP时的完成时间比Top 5厂商分别快1.8至55倍和2.6至4.8倍。
958 146
|
10月前
|
消息中间件 运维 安全
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验
游戏行业蓬勃发展,作为国内领先的 STEAM 游戏饰品交易的服务平台,看 C5GAME 如何利用 RocketMQ Serverless 技术,为千万级玩家提供流畅的游戏体验,同时降低成本并提升运维效率。
559 145
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验