JS的发布订阅模式
JS的发布订阅模式
这里要说明一下什么是发布-订阅模式
- 发布-订阅模式里面包含了三个模块,发布者,订阅者和处理中心。这里处理中心相当于报刊办事大厅。发布者相当与某个杂志负责人,他来中心这注册一个的杂志,而订阅者相当于用户,我在中心订阅了这分杂志。每当发布者发布了一期杂志,办事大厅就会通知订阅者来拿新杂志。这样在结合下面的图应该很好理解了。
- 其实就是将发布者和订阅者解耦了,在实际开发中,经常会遇到某个方法内处理很多的逻辑,最简单的就是直接在方法内直接写。这种是高度耦合的面向过程的写法。对于代码维护不友好。而发布-订阅模式就是将两者分离。我触发了某个事件(这里我们将触发该方法定义为事件),我只向调度中心通知,我并不知道调度中心内会怎么处理,有多少个人响应。我只管通知。而订阅者只管在调度中心订阅,有人调用它才响应。
- 还有一点就是假设我们有3个js文件,事件触发在a.js内,而响应该事件的在b.js和c.js内,要是用常规调用的方法的话,就要把b.js和c.js的方法传到a.js内。这是一个非常麻烦的操作。而发布-订阅模式是将调度中心挂在了全局,我们只管调用调度中心相应的方法注册和订阅。
ps:还有一点要注意的,很多人会把观察者模式和发布-订阅模式混淆,其实两者之间还是有点区别的,不过在本文我不会详细讲。
下面我们来实现一个发布-订阅模式的类
class Event {
constructor () {}
// 首先定义一个事件容器,用来装事件数组(因为订阅者可以是多个)
handlers = {}
// 事件添加方法,参数有事件名和事件方法
addEventListener (type, handler) {
// 首先判断handlers内有没有type事件容器,没有则创建一个新数组容器
if (!(type in this.handlers)) {
this.handlers[type] = []
}
// 将事件存入
this.handlers[type].push(handler)
}
// 触发事件两个参数(事件名,参数)
dispatchEvent (type, ...params) {
// 若没有注册该事件则抛出错误
if (!(type in this.handlers)) {
return new Error('未注册该事件')
}
// 便利触发
this.handlers[type].forEach(handler => {
handler(...params)
})
}
// 事件移除参数(事件名,删除的事件,若无第二个参数则删除该事件的订阅和发布)
removeEventListener (type, handler) {
// 无效事件抛出
if (!(type in this.handlers)) {
return new Error('无效事件')
}
if (!handler) {
// 直接移除事件
delete this.handlers[type]
} else {
const idx = this.handlers[type].findIndex(ele => ele === handler)
// 抛出异常事件
if (idx === -1) {
return new Error('无该绑定事件')
}
// 移除事件
this.handlers[type].splice(idx, 1)
if (this.handlers[type].length === 0) {
delete this.handlers[type]
}
}
}
}
ok到现在为止就已经实现了基本发布订阅的功能了,其实很简单,如果还有什么奇怪的需求,都可以通通往里面加。
下面是完整的使用demo
var event = new Event() // 创建event实例
// 定义一个自定义事件:"load"
function load (params) {
console.log('load', params)
}
event.addEventListener('load', load)
// 再定义一个load事件
function load2 (params) {
console.log('load2', params)
}
event.addEventListener('load', load2)
// 触发该事件
event.dispatchEvent('load', 'load事件触发')
// 移除load2事件
event.removeEventListener('load', load2)
// 移除所有load事件
event.removeEventListener('load')
希望大家转载时注明出处:https://www.cnblogs.com/suyuanli/p/9655699.html
JS的发布订阅模式的更多相关文章
- js设计模式-发布/订阅模式
一.前言 发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知. 就和用户 ...
- js设计模式--发布订阅模式
前言 本系列文章主要根据<JavaScript设计模式与开发实践>整理而来,其中会加入了一些自己的思考.希望对大家有所帮助. 概念 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的 ...
- [转]js设计模式—发布订阅模式
发布—订阅模式又叫观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在javascript开发中,一般用事件模型来替代传统的发布—订阅模式.本文将 ...
- js 实现发布订阅模式
/* Pubsub */ function Pubsub(){ //存放事件和对应的处理方法 this.handles = {}; } Pubsub.prototype = { //传入事件类型typ ...
- JS中的发布订阅模式
一. 你是如何理解发布订阅模式的 JS中的设计模式: 单例模式:处理业务逻辑 构造原型模式:封装类库,组件,框架,插件等 类库:jQuery 只是提供了一些常用的方法,可以应用到任何的项目中,不具备业 ...
- 从发布订阅模式入手读懂Node.js的EventEmitter源码
前面一篇文章setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop详细讲解了浏览器和Node.js的异步API及其底层原理Event Loop.本文会讲一下不 ...
- js里的发布订阅模式及vue里的事件订阅实现
发布订阅模式(观察者模式) 发布订阅模式的定义:它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布订阅模式在JS中最常见的就是DOM的事件绑定与触发 ...
- 4.js模式-发布-订阅模式
1. 发布-订阅模式 var observe = (function(){ var events = {}, listen, trigger, remmove; listen = function(k ...
- JS设计模式(5)发布订阅模式
什么是发布订阅模式(观察者模式)? 定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 主要解决:一个对象状态改变给其他对象通知的问题,而且 ...
随机推荐
- (八)Linux之挂载命令
挂载命令 其实挂载在Linux中可以理解为分配盘符的意思.想一下,比如一张光盘插入了Linux系统的 电脑上,要想读取其中的内容,需要做哪些操作呢?首先你要考虑的是这张外来光盘的的数据也是 外来的,如 ...
- 友盟消息推送api、python sdk问题、测试demo代码
一,友盟消息推送python服务端sdk地址和文档地址 1.sdk地址:http://dev.umeng.com/system/resources/W1siZiIsIjIwMTYvMDgvMTkvMT ...
- 2、Android-UI(关于Nine-Patch图片)
实例: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...
- face++
1.链表反转 2.快排 3.m*k n*k两矩阵计算欧几里得距离np.tile 4.链表排序,要求时间复杂度小于O(N^2),空间O(1),不允许改变链表的值 5.2sum及其变体 6.给一个数组 ...
- Swift 开发语法
文/Tuberose(简书作者)原文链接:http://www.jianshu.com/p/5e2d4c34f18e著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 简介 Swift 语 ...
- css让不同大小的图片适应div的大小,且不变形。
做成背景图片 单个 .imgdiv { width: 100px; // 你要的正方形 height: 100px; // 你要的正方形 background-image: url(/your/ima ...
- 利用kage把msf变成可视化远控平台
项目下载https://github.com/WayzDev/Kage/releases 这里用kali系统演示 1,先下载kage: 2,右击给予执行权限 3,启动msf msfconsole -q ...
- XIB
Xib加载的几种方法 - 简书 一天一点xib_10说说原理.优化方面的东西吧 - 简书 自定义View的封装和xib文件的使用详解|xiaoyou's blog 纯代码封装自定义View和XIB封装 ...
- iOS 中系统与 SDK 版本检测
一.编译时检测 1. 判断 SDK 是否是某个版本或更高版本 ifdef __IPHONE_11_0 2.判断当前需要支持的最低版本 __IPHONE_OS_VERSION_MIN_REQUIRED ...
- OpenStack(queens)最小化搭建记录——控制与计算共两个节点
境: 2台安装了centos7-minimal的主机 ip地址: 10.132.226.103/24 (controller) 10.132.226.104/24 (compute1) 1.配置主机名 ...
