JS中发布/订阅模式的简单应用

简介: JS中发布/订阅模式的简单应用

深入理解JavaScript中的发布/订阅模式

在现代的前端开发中,我们经常会遇到需要多个组件或模块间进行通信的情况。为了解耦这些组件,使它们之间的依赖关系降到最低,并实现更加灵活和可维护的代码,我们经常会使用一些设计模式。其中,发布/订阅模式(也被称为观察者模式)是一种非常常见且有用的模式。

什么是发布/订阅模式?

发布/订阅模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,它的所有依赖者(订阅者)都会自动收到通知并更新。

在个模式的好处自安于能够对代码进行解耦,实现了“高内聚,低耦合”的理念。

1.建立一个事件总线。

2.发布事件。

3.订阅事件。

//事件总线,管理事件
class Notcice {
    #arr = new Map()
    constructor() {

    }
    add(str, fn) {
        if (this.#arr.has(str)) {
            this.#arr.set(str, fn)
        } else {
            throw new Error("这个事件已经被注册了")
        }

    }
    emit(str, params) {
        if (this.#arr.has(str)) {
            this.#arr.get(str)(params);
        } else {
            throw new Error("别TM瞎掉")
        }
    }
}
//new 一个实例,并且一直用这个实例,保证我们的只有一个总线
let myNotice = new Notcice()
//发布一个eat事件
myNotice.add("eat", (params) => {
    console.log(`吃${params}`);
})
//订阅
myNotice.emit("eat", "苹果")

发布者(Publisher)

发布者是可以发送消息的对象,它们维护了一个或多个订阅者的列表,并在适当的时候通知它们。

订阅者(Subscriber)

订阅者是对特定事件感兴趣的对象,它们将自己注册到发布者上,以便在事件发生时接收通知。

事件(Event)

事件是发布者向订阅者发送的消息或通知。

JavaScript中的实现

在JavaScript中,我们可以使用原生的对象和数组来实现发布/订阅模式。下面是一个简单的例子:

class PubSub {
  constructor() {
    this.subscribers = {};
  }

  subscribe(event, callback) {
    if (!this.subscribers[event]) {
      this.subscribers[event] = [];
    }
    this.subscribers[event].push(callback);
  }

  publish(event, data) {
    if (this.subscribers[event]) {
      this.subscribers[event].forEach(callback => callback(data));
    }
  }
}

// 使用
const pubSub = new PubSub();

// 订阅者1
pubSub.subscribe('message', (data) => {
  console.log('订阅者1收到消息:', data);
});

// 订阅者2
pubSub.subscribe('message', (data) => {
  console.log('订阅者2收到消息:', data);
});

// 发布者发布消息
pubSub.publish('message', 'Hello, World!');

在这个例子中,我们创建了一个PubSub类,它有两个主要的方法:subscribepublishsubscribe方法用于注册事件和对应的回调函数,而publish方法用于发布事件并传递数据给所有订阅了该事件的回调函数。

应用场景

发布/订阅模式在前端开发中有着广泛的应用,下面列举了几个常见的场景:

1. 自定义事件

在复杂的单页应用(SPA)中,组件之间的通信经常需要跨越多个层级。使用发布/订阅模式,我们可以创建自定义事件,让组件在需要的时候触发这些事件,而其他组件可以订阅这些事件并在事件发生时执行相应的逻辑。

2. 状态管理

在前端状态管理库(如Redux、Vuex)中,发布/订阅模式是实现状态更新的核心机制。当状态发生变化时,所有订阅了该状态的组件都会收到通知并重新渲染。

3. 异步编程

在异步编程中,发布/订阅模式可以帮助我们解耦异步操作和它们的回调函数。例如,我们可以使用Promise或async/await语法来订阅一个异步操作的结果,并在操作完成时执行相应的逻辑。

4. 插件系统

在插件系统中,发布/订阅模式可以让插件之间以解耦的方式进行通信。插件可以订阅系统事件,并在事件发生时执行相应的操作,从而实现插件之间的协作和扩展。

注意事项

虽然发布/订阅模式非常有用,但在使用时也需要注意一些问题:

1. 内存泄漏

如果订阅者不再需要接收某个事件的消息,但没有取消订阅,那么当该事件再次发生时,订阅者的回调函数仍然会被执行。这可能会导致内存泄漏和不必要的计算。因此,我们需要在适当的时候取消订阅。

2. 事件命名冲突

如果不同的发布者发布了同名的事件,或者订阅者订阅了多个同名的事件,那么可能会发生事件命名冲突。为了避免这种情况,我们可以使用命名空间或唯一标识符来区分不同的事件。

3. 回调函数的执行顺序

在发布事件时,订阅者的回调函数是按照它们被注册的顺序依次执行的。如果回调函数的执行顺序很重要,我们需要确保它们按照正确的顺序注册。

结论

发布/订阅模式是一种非常强大且灵活的设计模式,它可以帮助我们解耦组件、降低依赖关系,并实现更加可维护和可扩展的代码。在前端开发中,我们可以利用JavaScript的原生特性来实现这种模式,并应用于自定义事件、状态管理、异步编程和插件系统等场景。但在使用时,我们也需要注意内存泄漏、事件命名冲突和回调函数的执行顺序等问题。通过合理地运用发布/订阅模式,我们可以编写出更加优雅和高效的前端代码。


是不是很简单啊?喜欢的小伙伴留言点赞关注吧!

相关文章
|
12天前
|
数据采集 JavaScript 前端开发
理解并应用:JavaScript响应式编程与事件驱动编程的差异
了解JavaScript的响应式编程与事件驱动编程至关重要。事件驱动编程基于事件触发函数执行,如用户交互或系统事件。响应式编程则关注数据流变化,利用Observables自动响应更新。在爬虫代理IP的Web Scraping示例中,两者分别通过axios和rxjs显示了数据抓取的不同处理方式。掌握这两者能提升异步操作的效率和代码质量。
理解并应用:JavaScript响应式编程与事件驱动编程的差异
|
1天前
|
JSON JavaScript 中间件
Express.js:构建轻量级Node.js应用的基石
**Express.js 概览**:作为Node.js首选Web框架,Express以其轻量、灵活和强大的特性深受喜爱。自2009年以来,其简洁设计和丰富中间件支持引领开发者构建定制化应用。快速开始:使用`express-generator`创建项目,安装依赖,启动应用。示例展示如何添加返回JSON消息的GET路由。Express适用于RESTful API、实时应用等多种场景,社区支持广泛,助力高效开发。
5 1
|
2天前
|
存储 前端开发 JavaScript
回调函数是JavaScript中处理异步编程的常见模式,常用于事件驱动和I/O操作。
【6月更文挑战第27天】回调函数是JavaScript中处理异步编程的常见模式,常用于事件驱动和I/O操作。它作为参数传递给其他函数,在特定条件满足或任务完成后被调用。例如,`asyncOperation`函数接受回调函数`handleResult`,模拟异步操作后,调用`handleResult`传递结果。这样,当异步任务完成时,`handleResult`负责处理结果。
10 1
|
9天前
|
JavaScript 前端开发 安全
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
|
23天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的代驾应用系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的代驾应用系统附带文章和源代码部署视频讲解等
165 21
|
12天前
|
设计模式 存储 JavaScript
【JavaScript】JavaScript对象设计哲学:八种模式塑造高效代码
【JavaScript】JavaScript对象设计哲学:八种模式塑造高效代码
18 5
|
17天前
|
前端开发 JavaScript 网络协议
深入探讨其在JavaScript中的应用
【6月更文挑战第12天】WebSockets是为解决HTTP协议在实时通信中的局限而生的一种全双工通信协议,基于TCP,适合在线聊天、游戏等场景。JavaScript中的WebSocket API使浏览器与服务器能建立持久连接,方便数据实时传输。通过创建WebSocket对象、监听事件(open、message、error、close)来管理连接、发送/接收数据及处理错误。相较于AJAX轮询和长轮询,WebSockets更高效实时,是现代Web实时应用的理想选择。
23 3
|
18天前
|
前端开发 JavaScript 开发者
函数式编程在JavaScript中的应用
【6月更文挑战第10天】本文探讨了函数式编程在JavaScript中的应用,介绍了函数式编程的基本概念,如纯函数和不可变数据。文中通过示例展示了高阶函数、不可变数据的使用,以及如何编写纯函数。此外,还讨论了函数组合和柯里化技术,它们能提升代码的灵活性和可重用性。掌握这些函数式编程技术能帮助开发者编写更简洁、可预测的JavaScript代码。
|
25天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的服装品牌的推广及应用网站附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的服装品牌的推广及应用网站附带文章和源代码部署视频讲解等
28 4
|
27天前
|
JavaScript Serverless 网络架构
Next.js与SSR:构建高性能服务器渲染应用
创建Next.js项目使用`create-next-app`,每个页面自动支持SSR。动态路由如`pages/posts/[id]`,在`getStaticPaths`和`getServerSideProps`中获取数据。利用静态优化和预渲染提升性能,动态导入减少初始加载时间。使用`next/image`优化图片,自定义服务器增加控制,集成第三方库如Redux。优化SEO,利用i18n支持多语言,使用Serverless模式和Web Workers。项目支持TypeScript,创建`_error.js`处理错误,部署到Vercel并使用工具进行性能监控和优化。
159 4