不论是在程序世界里还是现实生活中,发布—订阅模式的应用都非常广泛。我们先看一下现实中的例子。 
小明最近看上了一套房子,到了售楼处之后才被告知,该楼盘的房子早已售罄。好在售楼MM告诉小明,不久后还有一些尾盘推出。开发商正在办理相关手续,手续办好后便可以购买。但到底是什么时候,目前还没有人能够知道。 
于是小明记下了售楼处的电话,以后每天都会打电话过去询问是不是已经到了购买时间。除了小明,还有小红,小强,小龙也会每天向售楼处咨询这个问题。一个星期过后,售楼MM决定辞职,因为厌倦了每天回答1000个相同的电话。 
当然现实中没有这么笨的销售公司,实际上故事是这样的:小明离开之前,把电话号码留在售楼处。售楼MM答应他,新楼盘一推出就马上发信息通知小明。小红、小强、小龙也是一样,他们的电话号码都被记在售楼处的花名册上,新楼盘推出的时候,售楼MM会翻开花名册,遍历上面的电话号码,依次发送一条短信通知他们。

发布订阅模式的优点

    1. 可以广泛应用于异步编程,它可以代替我们传统的回调函数,我们不需要关注对象在异步执行阶段的内部状态,我们只关心事件完成的时间点。

    2. 取代对象之间硬编码通知机制,一个对象不必显式调用另一个对象的接口,而是松耦合的联系在一起 
      虽然不知道彼此的细节,但不影响相互通信。更重要的是,其中一个对象改变不会影响另一个对象。

我们实现一个简单地发布订阅模型:

 // 首先定义消息的发布者
const salesoffice = {}; // 定义缓存列表,存放订阅者的回调函数列表;
salesoffice.clientList =[]; // 设置订阅者 salesoffice.listen = function(key, fn){
if(!this.clientList[key]) {
this.clientList[key] = [];
}
this.clientList[key].push(fn);
} // 设置发布事件
salesoffice.trigger = function(){
var key = Array.prototype.shift.call(arguments),
fns = this.clientList[key];
if(!fns || fns.length === 0) {
return false;
}
for(var i = 0 , fn ; fn = fns[i++];) {
fn.apply(this, arguments);
}
} //示例 salesoffice.listen('aaaaa' , function(a, b){
console.log(a);
console.log( b);
}) salesoffice.listen('abcde' , function(a, b){
console.log(a);
console.log(b);
console.log(a+b);
}) console.log(salesoffice); salesoffice.trigger('aaaaa' , 100 , 200); // 100 200 300 salesoffice.trigger('abcde', 111 , 222); // 111 222 333

一个通用的发布订阅模型和事件

 // 定义发布/订阅模型
const event = {
// 设置缓存列表,存放订阅者的回调函数列表
list : [],
// 设置订阅者
listen : function(key , fn){
if(!this.list[key]){
this.list[key] = [];
}
// 将订阅的消息添加到缓存列表中
this.list[key].push(fn);
}, // 发布事件
trigger : function() {
const key = Array.prototype.shift.call(arguments),
fns = this.list[key];
if(!fns || fns.length === 0){
return false;
}
for(let i = 0 , fn ; fn = fns[i++];){
fn.apply(this, arguments);
}
}, // 取消订阅
remove : function(key , fn){
const fns = this.list[key];
// 如果key对应的消息没有订阅过的话,则返回
if(!fns) {
return false;
}
// 如果没有传入具体的回调函数,表示需要取消key对应消息的所有订阅
if(!fn) {
delete this.list[key]; //如果没有后续参数,则删除整个回调数组
}else {
for(let i = fns.length - 1 ; i>=0 ;i--) {
const _fn = fns[i];
if(_fn === fn) {
fns.splice( i, 1); // 删除订阅者的回调函数
}
}
}
}
}; const initEvent = function(obj) {
for(let i in event) {
obj[i] = event[i];
}
}; const shoeobj = {}; initEvent(shoeobj); shoeobj.listen('abcd' , function(a, b) {
console.log(a);
console.log(b);
}) shoeobj.listen('efgh' , function(a, b){
console.log(a);
console.log(b);
}) shoeobj.trigger('abcd' , 100 ,200); // 100 200 shoeobj.trigger('efgh' , 300, 500); // 300 500 shoeobj.remove('abcd'); shoeobj.trigger('abcd', 20, 50); // false

Javascript实现简单地发布订阅模式的更多相关文章

  1. js 最简单的发布订阅模式

    let _subscriber: any; function autorun(subscriber: Function) { _subscriber = subscriber; _subscriber ...

  2. Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 如何实现发布--订阅模式? 发布---订阅模式的代码封装 如何取消订阅事件? 全局--发布订阅对象代码封装 理解模块间通信 回到 ...

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

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

  4. [转] Javascript中理解发布--订阅模式

    发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 现实生活中的发布- ...

  5. [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  6. 【转】Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时 ...

  7. 《JavaScript设计模式与开发实践》-- 发布-订阅模式

    详情个人博客:https://shengchangwei.github.io/js-shejimoshi-fabudingyue/ 发布-订阅模式 1.定义 发布-订阅模式:发布-订阅模式又叫观察者模 ...

  8. JavaScript设计模式(发布订阅模式)

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

  9. 第五章 --- 关于Javascript 设计模式 之 发布-订阅模式

    先来个最简单的 发布订阅模式 document.body.addEventListener('click',function(){ alert(123); }); document.body.clic ...

随机推荐

  1. Golang 受欢迎的原因:大道至简

    前言 Golang自2009年发布第一个版本,2012年发布1.0版本.在这10年的时间里,不断有开发者加入Golang的阵营中,不断共建Golang生态.其中比较有代表性的Golang编写软件作品是 ...

  2. ElasticStack学习(八):ElasticSearch索引模板与聚合分析初探

    一.Index Template与Dynamic Template的概念 1.Index Template:它是用来根据提前设定的Mappings和Settings,并按照一定的规则,自动匹配到新创建 ...

  3. 7.30考试password

    先说地球人都看得出来的,该数列所有数都是p的斐波那契数列中所对应的数的次幂,所以一开始都以为是道水题,然而斐波那契数列增长很快,92以后就爆long long ,所以要另谋出路,于是乎向Ren_iva ...

  4. sql server编写通用脚本实现获取一年前日期的方法

    问题: 在数据库编程开发中,有时需要获取一年前的日期,以便以此为时间的分界点,查询其前后对应的数据量.例如:1. 想查询截止到一年前当天0点之前的数据量,以及一年前当天0点开始到现在的数据量.2. 想 ...

  5. MFC开发--截图工具

    近期学习了MFC的相关知识,MFC(Microsoft Foundation Classes)是微软公司提供的一个类库,可以这样简单理解,就是对于Win32的封装(MFC对windows API函数的 ...

  6. 个人永久性免费-Excel催化剂功能第43波-文本处理类函数增强

    Excel的函数有400多个,真正常用的50多个,而常有的文本处理类函数也不多,不是因为文本类处理简单,而是Excel真的有点挤牙膏式的每个版本更新那么几个小函数,普通用户等得急切,但实际上这些小函数 ...

  7. c语言进阶6-指针

    指针是c语言的一个重要组成部分 是c语言的核心.精髓所在,用好指针可以在c语言编程中起到事半功倍的效果.一方面,可以提高程序的编译效率和执行速度以及实现动态的存储分配:另一方面,使用指针可使程序更灵活 ...

  8. 使用Kubeadm创建k8s集群之部署规划(三十)

    前言 上一篇我们讲述了使用Kubectl管理k8s集群,那么接下来,我们将使用kubeadm来启动k8s集群. 部署k8s集群存在一定的挑战,尤其是部署高可用的k8s集群更是颇为复杂(后续会讲).因此 ...

  9. 如何处理MySQL经常出现CPU占用率达到99%

    如何处理MySQL经常出现CPU占用率达到99% 情况说明: 最近在自己购买的linux服务器上捣鼓了一个小项目,按理说不存在CPU占用率会达到100%的情况,但事实就是经常出现. 然后,我第一反应是 ...

  10. Flutter学习笔记(11)--文本组件、图标及按钮组件

    如需转载,请注明出处:Flutter学习笔记(10)--容器组件.图片组件 文本组件 文本组件(text)负责显示文本和定义显示样式,下表为text常见属性 Text组件属性及描述 属性名 类型 默认 ...