博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript实现简单地发布订阅模式
阅读量:5034 次
发布时间:2019-06-12

本文共 3434 字,大约阅读时间需要 11 分钟。

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

 

发布订阅模式的优点

 

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

    2. 取代对象之间硬编码通知机制,一个对象不必显式调用另一个对象的接口,而是松耦合的联系在一起 

      虽然不知道彼此的细节,但不影响相互通信。更重要的是,其中一个对象改变不会影响另一个对象。

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

 

1 // 首先定义消息的发布者 2 const  salesoffice = {}; 3  4 // 定义缓存列表,存放订阅者的回调函数列表; 5 salesoffice.clientList =[]; 6  7 // 设置订阅者 8  9 salesoffice.listen = function(key, fn){10     if(!this.clientList[key]) {11         this.clientList[key] = [];12     }13     this.clientList[key].push(fn);14 }15 16 // 设置发布事件17 salesoffice.trigger = function(){18     var key = Array.prototype.shift.call(arguments),19               fns = this.clientList[key];20     if(!fns  || fns.length === 0) {21         return false;22     }23     for(var i = 0 , fn ; fn = fns[i++];) {24         fn.apply(this, arguments);25     }26 }27 28 //示例29 30 salesoffice.listen('aaaaa' , function(a, b){31    console.log(a);32    console.log( b);33 })34 35 36  salesoffice.listen('abcde' , function(a, b){37     console.log(a);38     console.log(b);39     console.log(a+b);40 }) 41 42 console.log(salesoffice);43 44 salesoffice.trigger('aaaaa' , 100 , 200);            //  100  200  30045 46 salesoffice.trigger('abcde', 111 , 222);            //  111 222 333

 

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

1 // 定义发布/订阅模型 2 const event = { 3     // 设置缓存列表,存放订阅者的回调函数列表 4     list : [], 5     // 设置订阅者 6     listen :  function(key , fn){ 7         if(!this.list[key]){ 8             this.list[key] = []; 9         }10         // 将订阅的消息添加到缓存列表中11         this.list[key].push(fn);12     },13 14     // 发布事件15     trigger : function() {16         const key = Array.prototype.shift.call(arguments),17                   fns = this.list[key];18         if(!fns ||  fns.length === 0){19              return false;20         }21         for(let i = 0 , fn ; fn = fns[i++];){22              fn.apply(this, arguments);23         }24     },25 26     // 取消订阅27     remove : function(key , fn){28         const fns = this.list[key];29         // 如果key对应的消息没有订阅过的话,则返回30         if(!fns) {31             return false;32         }33         // 如果没有传入具体的回调函数,表示需要取消key对应消息的所有订阅34         if(!fn) {35             delete this.list[key]; //如果没有后续参数,则删除整个回调数组36         }else {37             for(let i = fns.length - 1 ; i>=0 ;i--) {38                 const _fn = fns[i];39                 if(_fn === fn) {40                     fns.splice( i, 1);   // 删除订阅者的回调函数41                 }42             }    43         }44     }45 };46 47 const initEvent = function(obj) {48     for(let i in event) {49         obj[i] = event[i];50     }51 };52 53 const shoeobj = {};54 55 initEvent(shoeobj);56 57 shoeobj.listen('abcd' , function(a, b) {58     console.log(a);59     console.log(b);60 })61 62 shoeobj.listen('efgh' , function(a, b){63     console.log(a);64     console.log(b);65 })66 67 shoeobj.trigger('abcd' , 100 ,200);             //   100  20068  69 shoeobj.trigger('efgh' ,  300, 500);           //  300  50070 71 shoeobj.remove('abcd');72 73 shoeobj.trigger('abcd', 20, 50);              //  false

 

转载于:https://www.cnblogs.com/liquanjiang/p/8982659.html

你可能感兴趣的文章
根据CPU核心数确定线程池并发线程数
查看>>
解决方法:CentOS7用yum安装软件显示错误:cannot find a valid baseurl for repo: base/7/x86_64...
查看>>
hive安装<1>
查看>>
jsp另外五大内置对象之-out获取缓冲区大小
查看>>
博客主Judge已跳槽搬家emmm
查看>>
2017.7.31 ELK+logback+redis的使用
查看>>
Win10系统怎样让打开图片方式为照片查看器
查看>>
Chrome 开发者工具的技巧
查看>>
codevs 1069 关押罪犯 并查集
查看>>
Mybatis用log4j输出日志,输出sql到控制台
查看>>
中国象棋
查看>>
enum
查看>>
ffmpeg在am335x上的移植 分类: ffmpeg-SDL-VL...
查看>>
Cisco AP-ROMMON升级AP镜像
查看>>
十天冲刺3
查看>>
80. Remove Duplicates from Sorted Array II
查看>>
数据库-mongodb-高级查询表达式
查看>>
struts2 ajax 实现方式
查看>>
文件上传控件
查看>>
LoadRunner HTTP脚本迭代处理的常见问题
查看>>