JavaScript实现与使用发布/订阅模式详解

JavaScript实现与使用发布/订阅模式详解

什么是发布/订阅模式?

发布/订阅模式(Publish/Subscribe Pattern)是一种在软件设计中广泛使用的模式,它将一个系统的组件分为两类:发布者(Publisher)和订阅者(Subscriber)。发布者负责发布事件(消息),订阅者通过注册事件来接收消息。

发布/订阅模式的应用场景

  • 客户端与服务端的数据交互
  • 一对多的通信,例如:聊天室、广播
  • 客户端GUI事件

发布/订阅模式的优点

  • 实现了订阅者和发布者的解耦
  • 可以精确控制订阅者处理什么事件
  • 支持一对多的事件处理

实现JavaScript发布/订阅模式

下面我们详细讲解如何使用JavaScript实现发布/订阅模式:

  1. 首先我们需要创建一个 PubSub 对象,该对象是我们发布/订阅模式的核心部分。
const PubSub = {
  subscribe(event, callback) {
    if (!this[event]) {
      this[event] = []
    }
    this[event].push(callback)
  },
  publish(event, data) {
    if (!this[event]) {
      return
    }
    this[event].forEach((callback) => callback(data))
  },
  unsubscribe(event, callback) {
    if (!this[event]) {
      return
    }
    this[event] = this[event].filter((cb) => cb !== callback)
  },
}
  1. 创建一个 Publisher 对象,该对象负责发布事件。
const Publisher = {
  publishEvent() {
    PubSub.publish('anEvent', { event: 'anEvent', data: '传递的数据' })
  },
}
  1. 创建一个 Subscriber 对象,该对象负责订阅事件。
const Subscriber1 = {
  callback(data) {
    console.log('Subscriber1 订阅到了事件:', data)
  }
}

const Subscriber2 = {
  callback(data) {
    console.log('Subscriber2 订阅到了事件:', data)
  }
}

PubSub.subscribe('anEvent', Subscriber1.callback)
PubSub.subscribe('anEvent', Subscriber2.callback)
  1. 最后,我们来测试一下上面的代码是否能够正常工作。
Publisher.publishEvent()
// 输出:
// Subscriber1 订阅到了事件: {event: "anEvent", data: "传递的数据"}
// Subscriber2 订阅到了事件: {event: "anEvent", data: "传递的数据"}

示例说明

下面我们通过两个示例来说明发布/订阅模式的使用。

示例1:购物车计算器

我们来编写一个购物车计算器,当我们添加或删除商品时,自动计算当前购物车的总价。

const ShoppingCart = {
  products: [],
  addProduct(product) {
    this.products.push(product)
    PubSub.publish('onCartUpdated', this.products)
  },
  removeProduct(productId) {
    this.products = this.products.filter((product) => product.id !== productId)
    PubSub.publish('onCartUpdated', this.products)
  }
}

const Total = {
  update(cart) {
    console.log('购物车价格更新了:', this.calculateTotal(cart))
  },
  calculateTotal(cart) {
    return cart.reduce((total, product) => total + product.price, 0)
  },
}

PubSub.subscribe('onCartUpdated', Total.update.bind(Total))
ShoppingCart.addProduct({ id: 1, price: 10 })
// 输出:购物车价格更新了: 10
ShoppingCart.addProduct({ id: 2, price: 5 })
// 输出:购物车价格更新了: 15
ShoppingCart.removeProduct(2)
// 输出:购物车价格更新了: 10

在上面的代码示例中,当我们添加或删除商品时,就会发出名为 onCartUpdated 的事件,Total 对象订阅了这个事件并且会在每次收到该事件时通过调用 Total.update() 方法来更新购物车价格。

示例2:事件总线

前端应用程序通常需要处理多个组件之间的通信,例如:我们需要在不同的组件之间共享数据或触发某些操作。这就需要使用到一个简单的事件总线来解决这个问题。

const EventBus = {
  events: {},
  on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = []
    }
    this.events[event].push(callback)
  },
  off(event, callback) {
    if (!this.events[event]) {
      return
    }
    this.events[event] = this.events[event].filter((cb) => cb !== callback)
  },
  emit(event, data) {
    if (!this.events[event]) {
      return
    }
    this.events[event].forEach((callback) => callback(data))
  },
}

const ComponentA = {
  created() {
    EventBus.on('componentB:clicked', this.updateData.bind(this))
  },
  updateData(data) {
    console.log('ComponentA 发现 componentB 被点击了:', data)
  },
}

const ComponentB = {
  clicked() {
    EventBus.emit('componentB:clicked', { text: '这是 componentB 发布的事件' })
  },
}

ComponentA.created()
ComponentB.clicked()
// 输出:ComponentA 发现 componentB 被点击了: {text: "这是 componentB 发布的事件"}

在上面的示例中,当 ComponentB 触发了点击事件,它就会发布一个名为 componentB:clicked 的事件,并将数据传递给所有订阅该事件的组件。我们通过使用 EventBus.on() 以及 EventBus.emit() 来维护订阅和发布行为。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript实现与使用发布/订阅模式详解 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • Lua 中 pairs 和 ipairs 的区别

    Lua 中 pairs 和 ipairs 都是用来遍历 table 中的键值对的函数。它们的主要区别在于遍历时的顺序和范围。 pairs 函数 pairs 函数遍历 table 中所有的 key-value 对,遍历的顺序是无序的。pairs 返回两个值:键和与键对应的值。示例代码如下: local t = {name = "Tom", …

    node js 2023年6月8日
    00
  • 如何通过javaScript去除字符串两端的空白字符

    要通过javaScript去除字符串两端的空白字符,可以使用String对象提供的trim()方法。以下是完整攻略: 1. 使用trim()方法去除字符串两端的空白字符 trim()方法可以去除字符串的两端空白字符(包括空格、制表符、换行符等)。使用方法如下: var str = " hello world! "; str = str.t…

    node js 2023年6月8日
    00
  • javascript实现二叉树遍历的代码

    对于”javascript实现二叉树遍历的代码”,我可以提供以下完整攻略: 一、什么是二叉树? 二叉树是一种常见的树形结构,它由一个根节点和两个子节点组成。每个子节点又可以分别拥有自己的子节点。二叉树中的节点可以分为左子节点、右子节点和根节点。左子节点一般小于等于右子节点,这种特性在搜索树的场景中很有用。 二、二叉树遍历 二叉树的遍历逐一访问二叉树中的每个节…

    node js 2023年6月8日
    00
  • JavaScript 关于事件循环机制的刨析

    JavaScript 关于事件循环机制的刨析 什么是事件循环机制 JavaScript 引擎采用的是单线程执行模式,只有一个调用堆栈,每一次执行上下文都会从调用堆栈依次出栈,为了解决程序中出现的异步执行问题,JavaScript 引入了事件循环机制。 事件循环机制是指,当 JavaScript 引擎执行完调用堆栈中所有任务后,会去检查任务队列中是否还有任务未…

    node js 2023年6月8日
    00
  • nodejs 图片预览和上传的示例代码

    下面是关于“nodejs 图片预览和上传”的完整攻略。 步骤一:安装依赖 在开始编写nodejs图片上传和预览的代码前,需要安装必要的依赖项。首先进入项目文件夹,打开命令行工具,执行以下命令: npm init -y 这个命令会自动生成一个package.json文件,保存项目的信息和依赖项。接下来,安装express和multer依赖包: npm inst…

    node js 2023年6月8日
    00
  • 利用Node.js如何实现文件循环覆写

    实现文件循环覆写可以通过Node.js的文件系统模块(fs)来完成。具体步骤如下: 引入fs模块 使用require语句将fs模块引入到项目中: const fs = require(‘fs’); 实现文件循环覆写函数 function overwriteFile(filePath, data, retries) { if (retries === 0) {…

    node js 2023年6月8日
    00
  • nodejs处理http请求实例详解之get和post

    Node.js处理HTTP请求实例详解之GET和POST 什么是HTTP请求? HTTP(Hyper Text Transfer Protocol)即超文本传输协议。它是Web客户端和服务器端进行通信的基础,它的主要特点是简单快速、灵活,是全球互联网的基础。 Node.js处理HTTP请求 Node.js是一个开源的、跨平台的JavaScript运行环境,它…

    node js 2023年6月8日
    00
  • vue中的使用token的方法示例

    当应用程序需要进行用户验证时,可以使用token来进行身份认证。Vue.js作为一种流行的前端框架,也支持使用token进行身份验证。现在让我们一起来学习如何在Vue.js应用程序中使用token进行身份认证。 步骤一:生成token 生成token的方法多种多样,这里我们使用jsonwebtoken来生成一个token值。 const jwt = requ…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部