一、前言

  发布订阅模式,基于一个主题/事件通道,希望接收通知的对象(称为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设计模式-发布/订阅模式的更多相关文章

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

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

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

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

  3. JS的发布订阅模式

    JS的发布订阅模式 这里要说明一下什么是发布-订阅模式 发布-订阅模式里面包含了三个模块,发布者,订阅者和处理中心.这里处理中心相当于报刊办事大厅.发布者相当与某个杂志负责人,他来中心这注册一个的杂志 ...

  4. javascript设计模式——发布订阅模式

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

  5. 设计模式-发布订阅模式(javaScript)

    1. 前言 2. 什么是发布订阅模式 3. 发布订阅优缺点 4. 举例 4. 总结 1. 前言 发布订阅者模式是为了发布者和订阅者之间避免产生依赖关系,发布订阅者之间的订阅关系由一个中介列表来维护.发 ...

  6. javascript 设计模式 -- 发布/订阅模式

    直接上代码: index.html : <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  7. js 实现发布订阅模式

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

  8. js 设计模式:观察者和发布订阅模式

    总是把这两个当作同一个模式,但其实是不太一样的,现在重温一下. 观察者模式 观察者直接订阅目标,当目标触发事件时,通知观察者进行更新 简单实现 class Observer { constructor ...

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

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

随机推荐

  1. 设计模式-(11)组合模式 (swift版)

    一,概念 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结 ...

  2. leetcode 783. Minimum Distance Between BST Nodes 以及同样的题目 530. Minimum Absolute Difference in BST

    Given a Binary Search Tree (BST) with the root node root, return the minimum difference between the ...

  3. 并不对劲的loj2179:p3714:[BJOI2017]树的难题

    题目大意 有一棵树,\(n\)(\(n\leq2*10^5\))个点,每条边\(i\)有颜色\(w_i\),共有\(m\)(\(m\leq n\))种颜色,第\(i\)种颜色的权值是\(c_i\)(\ ...

  4. 并不对劲的bzoj3626:loj2558:p4211:[LNOI2014]LCA

    题目大意 有一棵有\(n\)(\(n\leq5*10^4\))个点的树,\(q\)(\(q\leq5*10^4\))次询问,每次给出\(l,r,x\)表示询问所有编号在\([l,r]\)的点与点\(x ...

  5. 并不对劲的LCT

    LCT,是连猫树(link-cat-tree)的缩写.它是树链剖分和splay的结合版本. 由于有很多关于LCT的文章以及这并不是对劲的文章,并不对劲的人并不打算讲得太详细. 推荐:详细的LCT-&g ...

  6. bzoj 2726 任务安排

    题目大意: 机器上有N个需要处理的任务,它们构成了一个序列 把这些任务分成若干批 从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti 在每批任务开始前,机器需要启动时间S,而完成这批 ...

  7. uva 11401

    Triangle Counting Input: Standard Input Output: Standard Output You are given n rods of length 1, 2… ...

  8. Pascal输出星星

    program Project2; {$APPTYPE CONSOLE} uses SysUtils; var i,j:integer; begin { TODO -oUser -cConsole M ...

  9. Eclipse打开Android项目报Parsing Data for android-21 failed错误的解决办法(转载)

    转载:http://segmentfault.com/blog/hongliang/1190000000739285 今天手贱,用android命令打开SDK Manager下载了最新的Android ...

  10. [App Store Connect帮助]八、维护您的 App(5)生成产品报告

    您可以生成产品报告,详细介绍您所在机构中 App 目录的信息和设置,包括 App 内购买项目,以及 Game Center排行榜和成就的元数据. 首先您以不同类型请求产品报告,之后您会收到一封电子邮件 ...