从小区广场舞群聊,看懂前端 er 必懂的发布订阅模式

引子

你被小区群聊"骚扰"过吗? 某天凌晨5点,我被手机震醒------小区广场舞群又炸了: "张姐,今天音响音量调小点呗?" "李哥,占位的红布帮我挪挪,我带孙女晚点到" "王姨,新舞教学视频发群里了啊"

放下手机我突然顿悟:这不就是活生生的发布订阅模式吗!群主是事件中心,跳舞的是订阅者,发消息的是发布者... 前端er天天挂在嘴边的设计模式,原来早就渗透到生活里了。

什么是发布订阅?说白了就是"中间商赚差价"

先看个灵魂比喻:

  • 你关注了"稀土掘金"公众号(订阅事件)
  • 掘金小编发了篇干货文(发布事件)
  • 你收到推送并点开(执行回调)

这里的公众号平台 就是关键------它让订阅者和发布者互不认识,却能精准通信。这就是发布订阅的核心:通过第三方(事件中心)实现一对多通信

反观隔壁"观察者模式"就很耿直:发布者直接抱着订阅者的微信猛发消息(直接通信),想想都觉得窒息...

手把手实现一个"群聊管理器"(EventEmitter)

我们用代码还原小区群聊的功能,先搭个基础框架:

js 复制代码
class EventEmitter { 
 constructor() { 
  this.eventList = {}; // 存储事件列表,比如 { '广场舞通知': [张姐, 李哥] 
 } 
} 

1. 先实现"入群"功能(on方法)、、

想接收消息,得先入群吧?on方法就是干这个的:

js 复制代码
on(eventName, cb) {
  if (!this.eventList[eventName]) {
    this.eventList[eventName] = []; // 没这个群就新建一个
  }
  this.eventList[eventName].push(cb); // 拉人入群
}

比如张姐要听广场舞通知:

js 复制代码
eventEmitter.on('广场舞通知', () => console.log('张姐收到,马上到'));

2. 再搞"发通知"功能(emit方法)

群主发通知,群里所有人都能收到:

js 复制代码
emit(eventName) {
  if (this.eventList[eventName]) {
    const handlers = this.eventList[eventName].slice(); // 复制一份避免发消息时有人退群
    handlers.forEach(cb => cb()); // 挨个通知
  }
}

群主喊话:

js 复制代码
eventEmitter.emit('广场舞通知'); // 输出:张姐收到,马上到

3. "退群"功能也得有(off方法)

总有人想清静几天,off方法安排上:

js 复制代码
off(eventName, cb) {
  const callbacks = this.eventList[eventName];
  const index = callbacks.indexOf(cb);
  if (index !== -1) {
    callbacks.splice(index, 1); // 把人移出群
  }
}

4. 特殊需求:"只看一次"(once方法)

王姨只想看一次新舞教学,之后就退群:

js 复制代码
once(eventName, cb) {
  const wrap = () => {
    cb(); // 先执行回调
    this.off(eventName, wrap); // 看完就退群
  };
  this.on(eventName, wrap);
}

这波操作,堪称代码界的"阅后即焚"!

实战:用发布订阅解决"异步依赖"问题

比如有个场景:

  • fnA要等1秒后执行,完事通知大家
  • fnB订阅这个通知,收到后执行

用我们的EventEmitter轻松搞定:

js 复制代码
const eventEmitter = new EventEmitter();

// fnA:1秒后发布"next"事件
function fnA() {    
  setTimeout(() => {
    console.log('fnA 执行了');
    eventEmitter.emit('next'); // 通知大家
  }, 1000);
}

// fnB:订阅"next"事件
function fnB() {
  setTimeout(() => {
    console.log('fnB 执行了');
  }, 500);
}

eventEmitter.on('next', fnB);
fnA(); // 1秒后输出"fnA 执行了",接着输出"fnB 执行了"

没有回调地狱,代码清爽得像刚洗过澡~

总结:这模式到底香在哪?

  1. 解耦神器:发布者和订阅者互不关心对方是谁,只管发和收
  2. 灵活扩展:想加新功能?直接加个订阅者就行,不用改老代码
  3. 异步友好:处理各种异步操作(比如接口请求、定时器)时特别顺手

现在再看小区群聊,是不是觉得程序员的世界和现实无缝衔接了?下次被群消息烦的时候,不妨默念:"这是发布订阅模式,我懂!"------瞬间就高大上起来了有没有~ 最后

相关推荐
阿华的代码王国1 小时前
【Android】RecyclerView实现新闻列表布局(1)适配器使用相关问题
android·xml·java·前端·后端
汪子熙1 小时前
Angular 最新的 Signals 特性详解
前端·javascript
Spider_Man1 小时前
前端路由双雄传:Hash vs. History
前端·javascript·html
南方kenny1 小时前
CSS Grid 布局:从入门到精通,打造完美二维布局
前端·javascript·css
小泡芙丫1 小时前
从买房到代码:发布订阅模式的"房产中介"之旅
前端·javascript
企鹅吧1 小时前
前端导出 pdf 与 跑马灯效果 最佳实践
前端·javascript·vue.js
南方kenny1 小时前
移动端适配的利器:lib-flexible 原理与实战
前端·javascript·react.js
沫小北1 小时前
HarmonyOS 自定义日期选择器组件详解
前端
大土豆的bug记录2 小时前
鸿蒙拉起系统定位和app授权定位
前端·javascript·harmonyos
用户47949283569152 小时前
mcp是怎么和大模型进行交互的,有哪些交互方式
前端·人工智能