js设计模式之发布/订阅模式模式
两种模式存在一定区别
一、观察者模式(Observer)
观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进行更新。
在观察者模式中,Subject 对象拥有添加、删除和通知一系列 Observer 的方法等等,而 Observer 对象拥有更新方法等等。
// 定义一个主体对象
class Subject {
constructor() {
this.Observers = [];
}
add(observer) { //添加
this.Observers.push(observer)
}
remove(observer) {//移除
this.Observers.filter(item => item === observer);
}
notify() {
this.Observers.forEach(item => {
item.update();
})
}
}
//定义观察着对象
class Observer {
constructor(name) {
this.name = name;
}
update() {
console.log(`my name is:${this.name}`);
}
} //测试
let sub = new Subject();
let obs1 = new Observer('leaf111');
let obs2 = new Observer('leaf222');
sub.add(obs1);
sub.add(obs2);
sub.notify();
上述代码中,我们创建了 Subject 对象和两个 Observer 对象,当有关状态发生变更时则通过 Subject 对象的 notify 方法通知这两个 Observer 对象,这两个 Observer 对象通过 update 方法进行更新。
二、发布订阅模式(Publisher && Subscriber)
发布订阅模式指的是希望接收通知的对象(Subscriber)基于一个主题通过自定义事件订阅主题,被激活事件的对象(Publisher)通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。
let pubSub = {
subs: [],
subscribe(key, fn) { //订阅
if (!this.subs[key]) {
this.subs[key] = [];
}
this.subs[key].push(fn);
},
publish(...arg) {//发布
let args = arg;
let key = args.shift();
let fns = this.subs[key];
if (!fns || fns.length <= 0) return;
for (let i = 0, len = fns.length; i < len; i++) {
fns[i](args);
}
},
unSubscribe(key) {
delete this.subs[key]
}
}
//测试
pubSub.subscribe('name', name => {
console.log(`your name is ${name}`);
})
pubSub.subscribe('gender', gender => {
console.log(`your name is ${gender}`);
})
pubSub.publish('name', 'leaf333'); // your name is leaf333
pubSub.publish('gender', '18'); // your gender is 18
三、区别

如上图所示:
1、在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
2、在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
四、vue中的作用
Vue会遍历实例的data属性,把每一个data都设置为访问器,然后在该属性的getter函数中将其设为watcher,在setter中向其他watcher发布改变的消息。
//遍历传入实例的data对象的属性,将其设置为Vue对象的访问器属性
function observe(obj,vm){
Object.keys(obj).forEach(function(key){
defineReactive(vm,key,obj[key]);
});
}
//设置为访问器属性,并在其getter和setter函数中,使用订阅发布模式。互相监听。
function defineReactive(obj,key,val){
//这里用到了观察者模式,它定义了一种一对多的关系,让多个观察者监听一个主题对象,这个主题对象的状态发生改变时会通知所有观察者对象,观察者对象就可以更新自己的状态。
//实例化一个主题对象,对象中有空的观察者列表
var dep = new Dep();
//将data的每一个属性都设置为Vue对象的访问器属性,属性名和data中相同
//所以每次修改Vue.data的时候,都会调用下边的get和set方法。然后会监听v-model的input事件,当改变了input的值,就相应的改变Vue.data的数据,然后触发这里的set方法
Object.defineProperty(obj,key,{
get: function(){
//Dep.target指针指向watcher,增加订阅者watcher到主体对象Dep
if(Dep.target){
dep.addSub(Dep.target);
}
return val;
},
set: function(newVal){
if(newVal === val){
return
}
val = newVal;
//console.log(val);
//给订阅者列表中的watchers发出通知
dep.notify();
}
});
} //主题对象Dep构造函数
function Dep(){
this.subs = [];
}
//Dep有两个方法,增加订阅者 和 发布消息
Dep.prototype = {
addSub: function(sub){
this.subs.push(sub);
},
notify: function(){
this.subs.forEach(function(sub){
sub.update();
});
}
}
js设计模式之发布/订阅模式模式的更多相关文章
- JS 设计模式八 -- 发布订阅者模式
概念 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多(一个发布,多个观察)的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 优点 1 ...
- 浅谈js设计模式之发布 — 订阅模式
发布 — 订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在 JavaScript开发中,我们一般用事件模型来替代传统的发布 — ...
- js设计模式之发布订阅模式
1. 定义 发布-订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知. 订阅者(Subscriber)把自己想订阅的事件注册(Subscri ...
- 学习javascript设计模式之发布-订阅(观察者)模式
1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...
- [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1
<JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...
- JavaScript设计模式_05_发布订阅模式
发布-订阅模式,定义了对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都将得到通知.发布-订阅模式是使用比较广泛的一种模式,尤其是在异步编程中. /* * pre:发布-订阅 ...
- “一切都是消息”--MSF(消息服务框架)之【发布-订阅】模式
在上一篇,“一切都是消息”--MSF(消息服务框架)之[请求-响应]模式 ,我们演示了MSF实现简单的请求-响应模式的示例,今天来看看如何实现[发布-订阅]模式.简单来说,该模式的工作过程是: 客户端 ...
- “一切都是消息”--iMSF(即时消息服务框架)之【发布-订阅】模式
MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately)消息,所以iMSF就是 immediately Message S ...
- ActiveMQ发布-订阅消息模式
一.订阅杂志我们很多人都订过杂志,其过程很简单.只要告诉邮局我们所要订的杂志名.投递的地址,付了钱就OK.出版社定期会将出版的杂志交给邮局,邮局会根据订阅的列表,将杂志送达消费者手中.这样我们就可以看 ...
随机推荐
- [leed code 179] Largest Number
1 题目 Given a list of non negative integers, arrange them such that they form the largest number. For ...
- 程序员、技术领导、管理者各有烦恼,你占了几条?ZZ
Q1: 作为学生,你学习 SE的烦恼有哪些? http://blog.jobbole.com/101840/
- 代码面试集锦 1 - Uber
Given an array of integers, return a new array such that each element at index i of the new array is ...
- MySQL--Percona-XtraDB-Cluster 5.6安装笔记
安装环境: 有三台干净的CentOS 6的服务器,IP配置为:192.168.166.169,192.168.166.170,192.168.166.171,准备搭建三节点的Percona XtraD ...
- HSmartWindowControl 之 摄像头实时显示( 使用 WPF )
1.添加Halcon控件,创建WPF项目 在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见: HSmartWindowControl之安装篇 (Visual Studio ...
- 【转】OAuth2.0的refresh token
转载自http://www.html-js.com/?p=1297 最近看人人网的OAuth认证,发现他是OAuth2.0,之前一直看的是新浪的OAuth,是OAuth1.0. 二者还是有很多不同的, ...
- 【5】JMicro微服务-熔断降级
如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 1. 使用服务熔断降级特性,必须先启动Pubsub服务,服务监听服务,熔断器服务3个服务 先启动Pubsub及服务监听两 ...
- 【disruptor】1、关于disruptor中的SequenceBarrier对象
首先这个类的uml结构在disruptor中是这样的,里面只有部分的属性对象和函数内容,具体有什么作用,用到了再说,用不到我也不会... 1.那么这个对象有什么用呢? 注意我们这个类中有哪些属性: 我 ...
- System.Threading.ThreadAbortException: 正在中止线程
症状 如果使用 Response.End.Response.Redirect 或 Server.Transfer 方法,将出现 ThreadAbortException 异常.您可以使用 try-ca ...
- POJ 2578
#include<iostream> #include<stdio.h> #include<vector> using namespace std; int mai ...