首页 > 其他分享 >发布订阅模式的TS实现

发布订阅模式的TS实现

时间:2024-08-17 12:51:45浏览次数:4  
标签:订阅 CallbackFn string ... args TS 模式 eventName callback

简介

发布订阅模式是一种常用的用于解耦的模式。

它和观察者模式的区别在于:

  • 观察者模式:被观察者需要维护一个观察者的集合;
  • 发布订阅模式:通信双方互相不知道对方的存在,通过第三方事件总线进行通信。

发布订阅模式在前端领域很常见,例如:

  • Vue 框架中组件的$on$emit方法;
  • Node.js 中 EventEmitter 中的 onemit 方法。

图示

  1. 订阅者通过on方法注册事件:

    image-20240817114351978

  2. 发布者通过emit触发回调列表:

    image-20240817114550701

    发布者和订阅者双方不知道各自的存在,它们仅通过Event Bus进行通信。

实现

事件总线最基本的两个方法是 onemit

常见的设计还有两个方法是 offonceoff 用于注销事件,onceon 的特例,表示仅订阅一次。

函数签名

type CallbackFn = (...args: any[]) => void;

on(eventName: string, callback: CallbackFn): void;
emit(enentName: string, ...args: any): void;
off(eventName: string, callback: CallbackFn): void;
once(eventName: string, callback: CallbackFn): void;

实现思路

在事件总线中需要建立起事件名回调集合的映射:

  • on时,将回调添加到指定事件名的回调集合中;
  • emit时,遍历指定时间名的回调集合,依次执行其中的回调函数;

回调集合可以使用Set实现,也可以使用数组实现。

由于on的实现需要做去重,建议使用Set,比较方便。

once的实现:

once 可以基于 on 和 off 实现,先使用 on 注册,执行回调之后就执行 off 注销,从而实现仅触发一次。

代码

使用 TypeScript 实现。

首先声明一个回调函数的类型,简化后续代码:

type CallbackFn = (...args: any[]) => void;

然后是声明 EventBus 类,成员属性中使用对象建立起 “事件名与回调集合” 的映射关系:

class EventBus{
    events: Record<string, Set<CallbackFn>> = {};

    constructor(){}
	
    on(eventName: string, callback: CallbackFn){ /* ... */ }
    emit(eventName: string, ...args: any[]){/* ... */}
    off(eventName: string, callback: CallbackFn){/* ... */}
    once(eventName: string, callback: CallbackFn){/* ... */}
}

on

on(eventName: string, callback: CallbackFn){
    if(!this.events[eventName]){
        this.events[eventName] = new Set();
    }
    this.events[eventName].add(callback);
}
  • 如果事件名不存在,则要初始化创建一个 Set 用于记录。
  • 如果事件名存在,则直接将回调添加到 Set 中。

这段代码可以通过 短路运算符 简化:

on(eventName: string, callback: CallbackFn){
    (this.events[eventName] ??= new Set()).add(callback);
}

emit

遍历回调集合就

标签:订阅,CallbackFn,string,...,args,TS,模式,eventName,callback
From: https://www.cnblogs.com/feixianxing/p/18364223/publish-subscribe-pattern-typescript-implem

相关文章

  • Microsoft-Activation-Scripts
    Microsoft-Activation-Scriptskeywords:windowsoffice激活MicrosoftActivationScripts(MAS)AWindowsandOfficeactivatorusingHWID/Ohook/KMS38/OnlineKMSactivationmethods,withafocusonopen-sourcecodeandfewerantivirusdetections.官网:htt......
  • 发布订阅模式的TS实现
    简介发布订阅模式是一种常用的用于解耦的模式。它和观察者模式的区别在于:观察者模式:被观察者需要维护一个观察者的集合;发布订阅模式:通信双方互相不知道对方的存在,通过第三方事件总线进行通信。发布订阅模式在前端领域很常见,例如:Vue框架中组件的$on和$emit方法;Node.js......
  • 使用 prefetchComponents 进行组件预取
    title:使用prefetchComponents进行组件预取date:2024/8/17updated:2024/8/17author:cmdragonexcerpt:摘要:本文介绍Nuxt.js中的prefetchComponents功能,用于预取组件以提高用户体验。通过在客户端后台下载和缓存组件,确保在用户需要时快速加载。文章涵盖了prefetchComp......
  • Golang使用Option设计模式优雅处理可选参数
    go语言不像其他语言函数的参数可以设置默认值以下是参考第三方库的写法packagemainimport"fmt"typeUserstruct{namestringageintidint}//Option代表可选参数typeOptionfunc(foo*User)//WithName为name字段提供一个设置器funcWithName(name......
  • 设计模式---构建者模式(Builder Pattern)
    构建者模式(BuilderPattern)是一种创建型设计模式,旨在将复杂对象的构建过程与其表示分离。它允许使用相同的构建过程创建不同的表示。该模式通常用于构建复杂对象,这些对象由多个部分组成或具有多个可选属性。构建者模式的核心要素:Builder(构建者):定义构建对象的接口,声明创建部......
  • Datawhale X 魔搭 AI0夏令营 魔搭-AIGC文生图方向 Tsak 3 就要完成了...
    本文为AI方向小白记录暑期参加魔搭夏令营-AIGC文生图方向的Task01    报名赛事链接:可图Kolors-LoRA风格故事挑战赛_创新应用大赛_天池大赛-阿里云天池的赛制    欢迎所有小白,大神前来交流学习。一.初识ComfyUI    1.1什么是ComfyUI      ......
  • Datawhale X 魔搭 AI0夏令营 魔搭-AIGC文生图方向 Tsak 1
    本文为AI方向小白记录暑期参加魔搭夏令营-AIGC文生图方向的Task01    报名赛事链接:https://tianchi.aliyun.com/competition/entrance/532254    欢迎所有小白,大神前来交流学习。一.文生图相关基础知识介绍    1.1文生图的介绍        文......
  • 【Java Lambda系列】新玩法,用Lambda重构设计模式
    前言前面三章通过理论+案例的方式对Lambda的描述,应该能基本上解决大家日常开发中所遇到的Lambda问题,为了更好的展现Lambda魅力,和加深巩固Lambda知识点,今天咱们讨论Lambda如何重构设计模式!关于设计模式众所周知,设计模式是一群大佬程序员将对程序设计的经验归纳总结起来的......
  • Edge-TTS:文字转语音的魔法棒,让你的世界“声”动起来!
    嘿,听我说,Edge-TTS可不简单!想象一下,你正对着电脑屏幕上的密密麻麻的文字发愁,突然,一根神奇的“魔法棒”——Edge-TTS出现在你眼前。在Edge-TTS在线工具上你轻轻一点,那些静止的文字就像被施了魔法一样,瞬间“活”了起来,变成了一个个生动有趣的声音,在你的耳边跳跃、舞动。Edge-TTS的......
  • 字符输入流InputStreamReader day17
    packagecom.shujia.day17.ketang;importjava.io.FileInputStream;importjava.io.InputStreamReader;/*转换流(字符流)=字节流+编码表字符流:(当一个文件使用记事本打开能够看懂的时候,就可以用字符流)字符输入流:Reader-......