快速导航×

J*aScript设计模式_观察者与发布订阅实现2025-11-18 17:15:47
观察者模式中主题直接通知观察者,发布订阅模式通过事件中心解耦通信。前者适用于对象间紧密关联,如Model与View同步;后者适合跨模块通信,如Vue事件总线。两者均需注意取消订阅以避免内存泄漏。

javascript设计模式_观察者与发布订阅实现

观察者模式和发布订阅模式在J*aScript中常用于解耦组件之间的通信。虽然两者看起来相似,但它们的实现机制和使用场景略有不同。下面分别介绍这两种模式的核心思想与代码实现。

观察者模式(Observer Pattern)

观察者模式定义了一种一对多的依赖关系:当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

在这个模式中,被观察的对象(称为“主题”或Subject)维护一个观察者列表,并在状态变化时主动通知它们。

实现步骤:

  • Subject 提供添加、删除和通知观察者的方法
  • Observer 实现一个更新方法,用于接收通知
  • Subject 状态变化时,遍历观察者列表并调用其 update 方法

代码示例:

```j*ascript class Subject { constructor() { this.observers = []; }

addObserver(observer) { this.observers.push(observer); }

removeObserver(observer) { this.observers = this.observers.filter(obs => obs !== observer); }

notify(data) { this.observers.forEach(observer => observer.update(data)); } }

class Observer { constructor(name) { this.name = name; }

update(data) { console.log(${this.name} 收到通知:, data); } }

// 使用示例 const subject = new Subject(); const obs1 = new Observer('观察者A'); const obs2 = new Observer('观察者B');

subject.addObserver(obs1); subject.addObserver(obs2);

subject.notify('状态已更新!'); // 输出: // 观察者A 收到通知:状态已更新! // 观察者B 收到通知:状态已更新!

<H3>发布订阅模式(Publish-Subscribe Pattern)</H3>
<p>发布订阅模式引入了事件通道(或事件中心),发布者和订阅者之间没有直接引用。消息通过事件中心进行中转,实现更彻底的解耦。</p>
                    <div class="aritcle_card">
                        <a class="aritcle_card_img" href="/ai/2294">
                            <img src="https://img.php.cn/upload/ai_manual/001/246/273/175712858367437.png" alt="ChatCut">
                        </a>
                        <div class="aritcle_card_info">
                            <a href="/ai/2294">ChatCut</a>
                            <p>AI视频剪辑工具</p>
                            <div class="">
                                <img src="/static/images/card_xiazai.png" alt="ChatCut">
                                <span>1086</span>
                            </div>
                        &lt;/div>
                        <a href="/ai/2294" class="aritcle_card_btn">
                            <span>查看详情</span>
                            <img src="/static/images/cardxiayige-3.png" alt="ChatCut">
                        </a>
                    </div>
                
<p>与观察者模式不同,发布者不直接通知订阅者,而是将消息推送给事件中心,由事件中心分发给所有订阅该事件的消费者。</p>

<font color="#000000">
<strong>核心角色:</strong>
<ul>
  <li>Publisher:发布事件</li>
  <li>Subscriber:订阅感兴趣的事件</li>
  <li>Event Channel:负责事件的注册、触发和管理</li>
</ul>
</font>

<p><strong>代码示例:</strong></p>
```j*ascript
class EventCenter {
  constructor() {
    this.events = {};
  }

  // 订阅事件
  on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  }

  // 发布事件
  emit(event, data) {
    if (this.events[event]) {
      this.events[event].forEach(callback => callback(data));
    }
  }

  // 取消订阅
  off(event, callback) {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(cb => cb !== callback);
    }
  }

  // 只监听一次
  once(event, callback) {
    const wrapper = (data) => {
      callback(data);
      this.off(event, wrapper);
    };
    this.on(event, wrapper);
  }
}

// 使用示例
const eventBus = new EventCenter();

eventBus.on('news', (msg) => {
  console.log('新闻订阅者:', msg);
});

eventBus.on('news', (msg) => {
  console.log('另一位读者:', msg);
});

eventBus.on('weather', (info) => {
  console.log('天气预报:', info);
});

eventBus.emit('news', '今天发生了重大事件!');
// 输出:
// 新闻订阅者: 今天发生了重大事件!
// 另一位读者: 今天发生了重大事件!

eventBus.emit('weather', '明天晴,气温25℃');
// 输出:天气预报: 明天晴,气温25℃

观察者模式 vs 发布订阅模式

两者都实现了对象间的松耦合通信,但关键区别在于耦合度和控制权:

  • 观察者模式中,Subject 直接管理 Observer 列表,两者存在直接依赖
  • 发布订阅模式通过事件中心中介,发布者和订阅者完全不知道对方的存在
  • 发布订阅更适合复杂系统中的跨模块通信,如Vue的事件总线、Node.js的 EventEmitter
  • 观察者模式更适用于对象间紧密关联的场景,如MVC中的Model与View

基本上就这些。理解它们的区别有助于在实际项目中选择合适的通信机制。不复杂但容易忽略细节,比如取消订阅和内存泄漏问题。

以上就是J*aScript设计模式_观察者与发布订阅实现的详细内容,更多请关注其它相关文章!


# 遍历  # seo全网营销平台运营  # 泰安个人网站建设哪家好  # 大米推广营销案例范文怎么写  # 英山网站建设排名前十  # 燃灯教育SEO教程VIP下载  # 营销推广获客公司  # 太原建设电商网站  # 涧西定制网站推广  # 网站都有哪些推广方式  # 宜宾自考网站建设  # 相关文章  # 感兴趣  # 并在  # vue  # 在这个  # 明天  # 复用  # 另一位  # 发生了  # 适用于  # 区别  # app  # node  # node.js  # js  # java  # javascript 


相关栏目: 【 企业资讯168 】 【 行业动态20933 】 【 网络营销52431 】 【 网络学院91036 】 【 运营推广7012 】 【 科技资讯60970


相关推荐: React/Next.js中实现列表项的动态移动与状态管理:兼论唯一键的重要性  Golang如何实现状态模式管理对象状态_Golang State模式实现技巧  J*aScript:在map操作中高效处理空数组  批改网学生版PC登录 批改网官网登录系统入口  谷歌推RCS信息存档功能:公司可监控员工私密信息!  顺丰快件物流信息 官方网站查询入口  Windows10怎么开启存储感知 Windows10系统设置自动清理临时文件释放C盘空间【教程】  Go语言中JSON数据解析与字段访问教程  Golang如何实现容器化日志收集与分析_Golang容器日志收集分析方法  AO3官方可用镜像 Archive of Our Own网页版最新入口  优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践  学习通在线学习平台 学习通网页版直接进入课程中心  J*aScript map 方法中处理循环元素为空数组的策略  vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧  使用 Pandas 高效处理 .dat 文件:字符清理与数据计算  一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法  Composer如何在生产环境安全地执行composer update  抖音网页版怎么|直播|_抖音网页版开播操作指南  PDF文件体积过大处理_PDF压缩技巧详解  QQ邮箱正确登录入口_QQ邮箱官方网站使用地址  深入理解Google Cloud Datastore查询:祖先路径与数据一致性  Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议  如何解决电商平台定制报价请求的“黑洞”问题,SprykerQuoteRequest模块助你提升客户体验与销售效率  J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程  CSS Flexbox如何实现多行排列_flex-wrap wrap自动换行显示  J*aScript中高效管理与清空动态列表:避免循环陷阱  今日头条怎么同步内容到抖音_今日头条内容同步到抖音教程  怎么在浏览器上运行HTML文件_浏览器运行HTML文件技巧【技巧】  c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学  如何使用 Excel 发布器与 Power BI 分享 Excel 洞察  将HTML Canvas内容转换为可上传的图像文件(File对象)  Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】  AWS EC2实例间SQL Server连接超时:安全组配置与故障排除指南  126邮箱账号注册 电脑版登录入口  抖音网页版快捷访问 抖音网页版网页版入口操作教程  Highcharts 雷达图径向轴标签定制指南:利用多Y轴实现数值标注  C++ string find函数返回值npos详解_C++字符串查找失败的判断条件  AO3中文官网链接_AO3网页版稳定镜像站  c++如何使用Meson构建系统_c++比CMake更快的构建工具  Win11如何设置屏幕保护程序 Win11屏保设置与取消方法【教程】  消息称三星明年 2 月正式发布 HBM4,与 SK 海力士同台竞技  虚幻5科幻题材ARPG大作遭取消!本是《奇异人生》厂商新作  基于动态规划的房屋花卉种植最小成本算法详解  PyTorch模型训练效果不佳?深入剖析常见错误与调试技巧  Excel组合图表怎么做 Excel创建柱状图与折线组合图教程【图表】  抖音未来赚钱的新趋势 2025年值得关注的变现风口分析  Go Martini框架:动态服务解码后的图片内容  C++ vector二维数组定义_C++ vector of vector用法  c++如何解决菱形继承问题_c++虚继承与虚基类详解  Golang如何优雅处理error_Golang error处理最佳实践总结