从小区广场舞群聊,看懂前端 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. 异步友好:处理各种异步操作(比如接口请求、定时器)时特别顺手

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

相关推荐
呐谁吃饭了7 分钟前
网络安全学习-6
前端
北辰alk8 分钟前
深入剖析Redux中间件实现原理:从概念到源码
前端
Pedantic9 分钟前
SwiftUI ObservableObject 观察者模式学习笔记
前端
跟橙姐学代码10 分钟前
列表、元组与字典:Python开发者的三大必备利器,再向高手靠近一步
前端·python·ipython
蜗牛快跑12311 分钟前
拆巨资让 Claude Code 和 Codex 同时住进了我的终端里
前端·后端·ai编程
小高00714 分钟前
🔥🔥🔥Vue部署踩坑全记录:publicPath和base到底啥区别?99%的前端都搞错过!
前端·vue.js·面试
摸着石头过河的石头19 分钟前
HTTP内容类型:从基础到实战的全方位解析
前端·http·浏览器
luckyzlb20 分钟前
02- html && css
前端·css·html
AI@独行侠22 分钟前
04 - 【HTML】- 常用标签(下篇)
前端·html