js设计模式-发布/订阅模式
一、前言
发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为subscriber)通过自定义事件订阅主题,被激活事件的对象(称为publisher)通过发布主题事件的方式被通知。
就和用户订阅微信公众号道理一样,一个公众号可以被多个用户同时订阅,当公众号有新增内容时候,只要发布就好了,用户就能接收到最新的内容。
js中的事件监听机制就是一种观察者模式。
二、和观察者模式的区别
观察者模式:一个对象(称为subject)维持一系列依赖于它的对象(称为observer),将有关状态的任何变更自动通知给它们(观察者)。
1、Observer模式要求观察者必须订阅内容改变的事件,定义了一个一对多的依赖关系;
2、Publish/Subscribe模式使用了一个主题/事件通道,这个通道介于订阅着与发布者之间;
3、观察者模式里面观察者「被迫」执行内容改变事件(subject内容事件);发布/订阅模式中,订阅着可以自定义事件处理程序;
4、观察者模式两个对象之间有很强的依赖关系;发布/订阅模式两个对象之间的耦合读底
这是一个简单的实现,主要是创建一个对象,有三个属性(容器,订阅方法,发布方法)。将订阅者放入容器,发布,触发容器内的函数。
(function(){
//
function Public(){
//存放订阅者的容器
this.subscribers=[];
//添加订阅者
this.addSubscribers=function(fn){
let isExit = this.subscribers.some(function(sub){
return fn == sub;
})
if(!isExit){
this.subscribers.push(fn);
}
return this;
}
//发布消息
this.deliver = function(data){
this.subscribers.forEach(function(fn){
fn(data);
})
return this;
}
}
let a = function(data){
console.log("a:"+data);
}
let b = function(data){
console.log("b:"+data);
}
let c = function(data){
console.log("c:"+data);
}
var pub = new Public();
pub.addSubscribers(a).addSubscribers(b).addSubscribers(c);
pub.deliver("消息");
})()
2、可以看到观察者模式有如下优点
a、每一个订阅者都是相互独立的只和发布者有关系,与发布者是一对多的关系,也可以是一对一的关系。
b、每一个订阅者可以根据自己的需求来调用,而不影响其它订阅者
c、与第一种方式相比,第二种方式的代码可读性、可维护性强;
这是一个完整的实现
(function(win){
function Public(){
this.handlers={};
}
Public.prototype = {
//订阅事件
on:function(eventType,eventHandle){
var self = this;
if(!(eventType in self.handlers)){
self.handlers[eventType] = [];
}
self.handlers[eventType].push(eventHandle);
return this;
},
emit:function(eventType){
//如果调用函数传了多个参数,eventType指第一个参数,arguments是一个对象,参数序号是key指,同时也给他length
//看起来像数组,其实不是数组。
var self = this;
//去除第一个事件类型的参数,使用call改变this指向
//使用slice的对象需要由length属性,所以arguments才能使用成功。
var handleArgs = Array.prototype.slice.call(arguments,1);
console.log(handleArgs);
for (var i =0; i<self.handlers[eventType].length;i++) {
//使用apply,订阅者的调用对象就是Public,不适用就是数组对象。
self.handlers[eventType][i].apply(self,handleArgs);
}
return this;
},
off:function(eventType,eventHandle){
var currentEvent = this.handlers[eventType];
var len = 0;
if(currentEvent){
len = currentEvent.length;
if(eventHandle == undefined){
currentEvent[eventType] = [];
}else{
for (var i = len-1;i >= 0;i--) {
if(currentEvent[i] == eventHandle){
currentEvent.splice(i,1);
}
}
}
}
}
}
var a = function(data){
console.log(this);
console.log("a"+data);
}
var b =function(data){
console.log("b"+data);
}
var pub = new Public();
pub.on("click",a).on("click",b);
pub.emit("click","xiaoxi");
})(window)
参考博主的文章:https://www.cnblogs.com/leaf930814/p/9014200.html
js设计模式-发布/订阅模式的更多相关文章
- js设计模式--发布订阅模式
前言 本系列文章主要根据<JavaScript设计模式与开发实践>整理而来,其中会加入了一些自己的思考.希望对大家有所帮助. 概念 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的 ...
- [转]js设计模式—发布订阅模式
发布—订阅模式又叫观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在javascript开发中,一般用事件模型来替代传统的发布—订阅模式.本文将 ...
- JS的发布订阅模式
JS的发布订阅模式 这里要说明一下什么是发布-订阅模式 发布-订阅模式里面包含了三个模块,发布者,订阅者和处理中心.这里处理中心相当于报刊办事大厅.发布者相当与某个杂志负责人,他来中心这注册一个的杂志 ...
- javascript设计模式——发布订阅模式
前面的话 发布—订阅模式又叫观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在javascript开发中,一般用事件模型来替代传统的发布—订阅模 ...
- 设计模式-发布订阅模式(javaScript)
1. 前言 2. 什么是发布订阅模式 3. 发布订阅优缺点 4. 举例 4. 总结 1. 前言 发布订阅者模式是为了发布者和订阅者之间避免产生依赖关系,发布订阅者之间的订阅关系由一个中介列表来维护.发 ...
- javascript 设计模式 -- 发布/订阅模式
直接上代码: index.html : <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- js 实现发布订阅模式
/* Pubsub */ function Pubsub(){ //存放事件和对应的处理方法 this.handles = {}; } Pubsub.prototype = { //传入事件类型typ ...
- js 设计模式:观察者和发布订阅模式
总是把这两个当作同一个模式,但其实是不太一样的,现在重温一下. 观察者模式 观察者直接订阅目标,当目标触发事件时,通知观察者进行更新 简单实现 class Observer { constructor ...
- JS设计模式(5)发布订阅模式
什么是发布订阅模式(观察者模式)? 定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 主要解决:一个对象状态改变给其他对象通知的问题,而且 ...
随机推荐
- FunsionCharts Demo
原文路径:http://www.cnblogs.com/xuhongfei/archive/2013/04/12/3016882.html 一.简介 Ø FusionCharts 是InfoSoft ...
- YTU 1002: Home Work
1002: Home Work 时间限制: 1000 Sec 内存限制: 64 MB 提交: 288 解决: 41 题目描述 临近开学了,大家都忙着收拾行李准备返校,但I_Love_C却不为此担心 ...
- ubuntu中pytesseract 安装与使用示例
1. 安装 tesseract-ocr 包 安装方法: sudo apt-get install tesseract-ocr 2. 安装 PIL PIL(python imaging library) ...
- http_load常见问题及解决方案
1.错误信息:byte count wrong http_load在处理时会去关注每次访问同一个URL返回结果(即字节数)是否一致,若不一致就会抛出byte count wrong 所以动态页面可以忽 ...
- wamp的手动安装
Wamp的手动安装 (http://www.cnblogs.com/homezzm/archive/2012/08/01/2618062.html) 一.Apache2.4安装 1.修改\Apache ...
- Excel学习 -- 数据透视表功能
Excel -- 数据透视表基础 数据透视表(Pivot Table)是一种交互式的表,可以进行某些计算,如求和与计数等.所进行的计算与数据跟数据透视表中的排列有关. 之所以称为数据透视表,是因 ...
- Linux 常用命令十六 文件权限管理
一.ls -l 各段含义 wang@wang:~/workpalce/threading$ ls -l 总用量 drwxrwxr-x wang wang 12月 : a -rw-rw-r-- wang ...
- bzoj 4818: [Sdoi2017]序列计数【容斥原理+dp+矩阵乘法】
被空间卡的好惨啊---- 参考:http://blog.csdn.net/coldef/article/details/70305596 容斥,\( ans=ans_{没有限制}-ans{没有质数} ...
- Unix\Linux | 总结笔记 | 用户管理
1. useradd [选项] 用户名 用于创建新的用户 useradd命令中的用户参数以及作用 参数 作用 -d 指定用户的家目录(默认为/home/username) -e 账户的到期时间,格 ...
- poj 3253 Fence Repair (水哈夫曼树)
题目链接: http://poj.org/problem?id=3253 题目大意: 有一根木棍,需要截成n节,每节都有固定的长度,一根长度为x的木棒结成两段,需要花费为x,问截成需要的状态需要最小的 ...