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的发布订阅模式的更多相关文章

  1. js设计模式-发布/订阅模式

    一.前言 发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知. 就和用户 ...

  2. js设计模式--发布订阅模式

    前言 本系列文章主要根据<JavaScript设计模式与开发实践>整理而来,其中会加入了一些自己的思考.希望对大家有所帮助. 概念 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的 ...

  3. [转]js设计模式—发布订阅模式

    发布—订阅模式又叫观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在javascript开发中,一般用事件模型来替代传统的发布—订阅模式.本文将 ...

  4. js 实现发布订阅模式

    /* Pubsub */ function Pubsub(){ //存放事件和对应的处理方法 this.handles = {}; } Pubsub.prototype = { //传入事件类型typ ...

  5. JS中的发布订阅模式

    一. 你是如何理解发布订阅模式的 JS中的设计模式: 单例模式:处理业务逻辑 构造原型模式:封装类库,组件,框架,插件等 类库:jQuery 只是提供了一些常用的方法,可以应用到任何的项目中,不具备业 ...

  6. 从发布订阅模式入手读懂Node.js的EventEmitter源码

    前面一篇文章setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop详细讲解了浏览器和Node.js的异步API及其底层原理Event Loop.本文会讲一下不 ...

  7. js里的发布订阅模式及vue里的事件订阅实现

    发布订阅模式(观察者模式) 发布订阅模式的定义:它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布订阅模式在JS中最常见的就是DOM的事件绑定与触发 ...

  8. 4.js模式-发布-订阅模式

    1. 发布-订阅模式 var observe = (function(){ var events = {}, listen, trigger, remmove; listen = function(k ...

  9. JS设计模式(5)发布订阅模式

    什么是发布订阅模式(观察者模式)? 定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 主要解决:一个对象状态改变给其他对象通知的问题,而且 ...

随机推荐

  1. ArcFac_C#_DEMO开发

    手上有一个项目,需要检验使用本程序的,是否本人!因为在程序使用前,我们都已经做过头像现场采集,所以源头呢是不成问题的,那么人脸检测,人脸比对,怎么办呢?度娘了下,目前流行的几个人脸检测,人脸比对核心, ...

  2. VC++6.0中碰到Cannot access the ClassView information file.ClassView information will not be avaible.的解决方法

    一般情况下是由于类视图文件损坏了,这是经常会发生的现象. 解决步骤: 1.关闭工程,2.删除工程下.clw .ncb 文件及/debug目录,3.重建工程build all. 具体解释如下: dsp ...

  3. week9:Recommender Systems

    Collaborative  filtering 的原理不是很理解? xi   是每一步电影的特征向量,表示浪漫/动作

  4. Oracle编辑数据时提示:这些查询结果不可更新,请使用ROWI或者SELECT……FOR UPDATE获得可更新结果

    我们在对Oracle数据库进行操作时,有时会在查询完结果后想要对其中的某些数据进行操作,当我们点击编辑(一个锁标志)是,会提示我们上述问题中的错误:这些查询结果不可更新,请使用ROWI或者SELECT ...

  5. POJ 1157 LITTLE SHOP OF FLOWERS (超级经典dp,两种解法)

    You want to arrange the window of your flower shop in a most pleasant way. You have F bunches of flo ...

  6. CC2640R2F&TI-RTOS 拿到 TI CC2640R2F 开发板 第一件事就是移植串口驱动,重定向 printf

    /* * board_uart.c * * Created on: 2018年7月3日 * Author: admin */ #include "board_uart.h" #in ...

  7. Spring 事务传播行为的使用

                                                                                                        ...

  8. iOS原生分享功能

    iOS_系统原生分享 - CSDN博客 通过UIActivityViewController实现更多分享服务 - 简书 UIActivity - UIKit _ Apple Developer Doc ...

  9. 如何设计处优秀的Restful API

    只知道遵规循矩的程序员是假程序员,任何技术都是不断发明创造改进的. 如何设计处优秀的Restful API?  盲目跟风,设计糟糕的Resful API = 浪费时间 ! 不啰嗦,直接进入技术主题: ...

  10. struct tm

    struct tm { int tm_sec; /* 秒–取值区间为[0,59] */ int tm_min; /* 分 - 取值区间为[0,59] */ int tm_hour; /* 时 - 取值 ...