设计模式 -- 发布订阅模式

发布订阅模式:
订阅者把自己想订阅的事件注册到调度中心,当发布者发布该事件到调度中心,也就是该事件触发时,由调度者统一调度订阅者注册到调度中心的处理代码。
在javaScript 中我们一般使用事件模型来代替传统的发布订阅模式。
在这里插入图片描述

  1. 结构:在发布订阅模式中,有一个中介者来管理发布者和订阅者之间的关系。
  2. 关系:发布者和订阅者不直接耦合,他们通过中间进行通信。发布者将消息发布给中介者,然后中介者将消息传递给所有的订阅者。
  3. 通知方式:订阅者通过向中介者注册感兴趣的事件或主题,中介者在收到消息后负责将消息分发给所有的订阅者。

可以广泛应用于异步编程中,这是一种替代传递回调函数的方案。
可以取代对象之间硬编码的通知机制,一个对象不能再显示地调用另外一个对象的某个接口。

从建构上看,无论是MVC还是MVVM.都少不了发布订阅模式的参与,而且javaScript本身也是一门基于事件驱动的语言。

简单理解:
DOM 事件, js简单的发布订阅模式

document.getElementById('myBtn').addEventListener('click', function() {
	alert('hellow word!')
})

简单的发布订阅模式

中介者
let e = {
	_callback: [],
	on(callback) {
		// 订阅一件事,当这件事发生时,触发相应的函数
		// 订阅就是将函数放到数组中
		this._callback.push(callback)
	},
	emit(value) {
		this._callback.forEach(method => {
			method(value)
		})
	}
}
// 订阅
e.on(function(value) {
	console.log(value + 'aa的订阅')
})
// 订阅
e.on(function(value) {
	console.log(value + 'bb的订阅')
})
// 发布
e.emit('发布')

自定义事件

let salesOffices = {
	clientList: {}
	listen(key, fn) {
		if (!this.clientList[key]) {
			this.clientList[key] = []
		}
		this.clientList[key].push(fn)
	},
	tigger() { // 发布消息
		let key = Array.prototype.shift.call(arguments) // 取出消息类型 取出实参
		let fns = this.clientList[key]

		if (!fns || fns.length === 0) {
			return false
		}
		
		for(let fn of fns) {
			fn.apply(this, arguments)  
		}
	}
}

// 例子
salesOffices.listen('squareMeter88', price => console.log(`价格 = ${price}`))
salesOffices.listen('squareMether110', price => console.log(`价格 = ${price}`))

salesOffices.trigger('squareMether88', 2000000)
salesOffices.trigger('squareMether110', 3000000)

通用的实现
通用的一种封装,实现了订阅、发布、取消

const event = {
	clientList: [],
	listen: function(key, fn) {
		if (!this.clientList[key]) {
			this.clientList[key] = []
		}
		this.clientList[key].push(fn)
	}
	trigger: function() {
		const key = Array.prototype.shift.call(arguments)
		const fns = this.clientList(key)
		
		if (!fns || fns.length === 0) {
			return false
		}
		for(let i = 0, fn; fn = fns[i++];) {
			fn.apply(this, arguments)
		}
	}
	remove: function(key, fn) {
		let fns = this.clientList[key];
		if (!fns) {
			return false
		}
		if (!fn) {
			fns && (fns.length = 0)
		} else {
			for(let i = fns.length -i; 1 >= 0; i-- ) {
				let _fn = fns[i]
				if (_fn === fn) {
					fns.splice(1,1)
				}
			}
		}
	} 
}
const installEvent = function( obj ){
    obj = { ...obj, ...event }
};

let salesOffices = {};
installEvent(salesOffices);

salesOffices.listen( 'squareMeter88', fn1 = function(price){    // 小明订阅消息
    console.log('价格= ' + price);
});

salesOffices.listen( 'squareMeter100', fn2 = function(price){     // 小红订阅消息
    console.log('价格= ' + price );
});

salesOffices.remove('squareMeter88', fn1);    // 删除小明的订阅

salesOffices.trigger('squareMeter88', 2000000);    // 输出:2000000
salesOffices.trigger('squareMeter100', 3000000);    // 输出:3000000

Veu中使用发布订阅
vue 提供了一个简单的事件系统,通过 vm.$emit 发布事件,vm.$on 订阅事件。这种机制类似于发布-订阅模式,允许组件之间进行松散耦合的通信。
在vue 中使用发布订阅模式的例子:
使用EventBus: 你可以创建一个简单的EventBus, 用于在不同组件之间进行通信。

// EventBus.js
import Vue from 'vue'
export const EventBus = new Vue()

// componentsA.vue
import { EventBus } from  './EventBus'
export default {
	methods: {
		sendMessage() {
			EventBus.$emit('message', 'hello from ComponentA!')
		}
	}
}

// componentsB.vue
import { EventBus } from './EventBus'
export default {
	methods: {
		sendMessage() {
			EventBus.$on('message', message => {
				console.log('Reveived message in ComponentB:', message)
			})
		}
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/529007.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文搞懂路由器2.4G和5G的区别,以及双频合一模式

我们知道,无线路由器是平时生活和工作中最常见不过的一个无线设备,通过它我们的手机、笔记本、智能电视、摄像头等,都可以接入互联网。 其实WiFi在1998年就开始使用了,当时仅仅是在欧美地区小范围使用,我们国家在2008年…

关于Ansible模块 ④

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 继《关于Ansible的模块 ①》、《关于Ansible的模块 ②》与《关于Ansible的模块 ③》之后,继续学习ansible常用模块之…

C++流程控制语句:嵌套循环案例分析【九九乘法表】

在C编程中,循环语句的嵌套是一种常见且强大的技术手段,它允许我们将多个循环结构相互嵌套,形成多维循环。不论是for循环、while循环还是do…while循环,均可以进行嵌套。 而在实践中,由于for循环具有明确的循环变量初…

[法规规划|数据概念]数据要素市场三月速递

“ 代表关注,市场活跃,发展迅速” 01—听听两会代表怎么说 在2024年的全国两会期间,数据要素作为新型的生产要素受到广泛关注,众多代表围绕数据要素市场化、立法、安全监管、人才培养及基础设施建设等方面,积极建言献策…

基于centos7安装docker+k8s+KubeSphere

实验环境:(每个服务器推荐内存为8G) 服务器 ip地址 主机名 centos7 192.168.80.1…

模型量化——NVIDIA——方案选择(PTQ、 partialPTQ、 QAT)

PTQ、 partialPTQ、 QAT 选择流程 PTQ、 partialPTQ、 QAT 咨询NVIDIA 官方后,他们的校正过程一致,支持的量化算子本质是一样的,那么如果你的算子不是如下几类,那么需要自己编写算子。参考TensorRT/tools/pytorch-quantization/py…

数据库入门-----SQL基础知识

目录 📖前言: 📑SQL概述&&通用语法: 🐳DDL: 🐻操作数据库: 🐞数据类型: 🦉操作表: 🦦DML: 语法规则&#x…

helm与k8基础

文章目录 一、helm二、K8S/K3S1.K8S基本组件1.1 资源对象1.2 核心组件1.3典型的创建 Pod 的流程1.4 Kubernetes 多组件之间的通信原理 三、容器运行时 Containerd1.查看当前k3s使用的容器运行时CRI2.K3S修改docker为运行环境3. Containerd 参考 一、helm Helm是Kubernetes的包…

吴恩达机器学习理论基础解读—线性模型(单一特征拟合)

吴恩达机器学习理论基础——线性模型 机器学习最常见的形式监督学习,无监督学习 线性回归模型概述 应用场景一:根据房屋大小预测房价 应用场景二:分类算法(猫狗分类) 核心概念:将训练模型的数据称为数…

使用C语言函数对数组进行操作

前言 在我们了解数组和函数之后,我们对数组和函数进行结合,之后完成一些操作吧 题目描述 杰克想将函数与数组结合进行一些操作,以下是他想要达到的效果,请你帮帮他吧! 创建一个整型数组,完成对数组的操作 1…

Taro框架中的H5 模板基本搭建

1.H5 模板框架的搭建 一个h5 的基本框架的搭建 基础template 阿乐/H5 Taro 的基础模板

人民网至顶科技:《开启智能新时代:2024中国AI大模型产业发展报告发布》

​3月26日,人民网财经研究院与至顶科技联合发布《开启智能新时代:2024年中国AI大模型产业发展报告》。该报告针对AI大模型产业发展背景、产业发展现状、典型案例、挑战及未来趋势等方面进行了系统全面的梳理,为政府部门、行业从业者以及社会公…

推荐一款自动化测试神器---Katalon Studio

Katalon Studio介绍 Katalon Studio 是一款在网页应用、移动和网页服务方面功能强大的自动化测试解决方案。基于 Selenium 和 Appium框架,Katalon Studio集成了这些框架在软件自动化方面的优点。这个工具支持不同层次的测试技能集。非程序员也可以快速上手一个自动…

5分钟了解清楚【osgb】格式的倾斜摄影数据metadata.xml有几种规范

数据格式同样都是osgb,不同软件生产的,建模是参数不一样,还是有很大区别的。尤其在应用阶段。 本文从建模软件、数据组织结构、metadata.xml(投影信息)、应用几个方面进行了经验性总结。不论您是初步开始建模&#xf…

Windows Server 2008添加Web服务器(IIS)、WebDAV服务、网络负载均衡

一、Windows Server 2008添加Web服务器(IIS) (1)添加角色,搭建web服务器(IIS) (2)添加网站,关闭默认网页,添加默认文档 在客户端浏览器输入服务器…

力扣LCR143---子结构判定(先序递归、Java、中等题)

题目描述: 给定两棵二叉树 tree1 和 tree2,判断 tree2 是否以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。 注意,空树 不会是以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。 示例 1: 输入:tree…

你真的了解区块链游戏吗?

随着区块链技术的不断发展和普及,越来越多的人开始关注区块链游戏这一新兴领域。然而,很多人对于区块链游戏的了解仅限于一些表面的概念和特点,真正深入了解的人并不多。那么,你真的了解区块链游戏吗? 首先&#xff0…

12.java openCV4.x 入门-HighGui之图像窗口显示

专栏简介 💒个人主页 📰专栏目录 点击上方查看更多内容 📖心灵鸡汤📖我们唯一拥有的就是今天,唯一能把握的也是今天建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫 🧭文…

【每日刷题】Day7

【每日刷题】Day7 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 206. 反转链表 - 力扣(LeetCode) 2. 203. 移除链表元素 - 力扣(…