JavaScript中发布/订阅模式的简单实例


Posted in Javascript onNovember 05, 2014

上次研究观察者模式,很多文章说它也叫Subscribe/Publish(发布/订阅模式)。可在《Javascript设计模式》一书中,这两种模式还是有些区别的。书中原话如下:

1.Observer模式要求希望接收到主题通知者的观察者必须订阅内容改变的事件。

2.Subscribe/Publish模式使用了一个主题/事件通道,这个通道介于订阅者和发布者之间。该事件系统允许代码定义应用程序的特定事件,该事件可以传递自定义参数,自定义参数包含订阅者所需要的值。其目的是避免订阅者和发布者产生依赖关系。

与Observer模式不同之处在于它允许任何订阅者执行适当的事件处理程序来注册和接收发布者发出的通知。

好吧,不明觉厉。下面是我的理解:

1.观察者模式中,目标对象负责维护观察者。发布/订阅模式中发布者不关心订阅者,只负责把消息丢出去就不管了。

2.观察者模式中,观察者要提供一个接口,然后当目标对象发生改变时调用此接口使自身状态和目标状态保持一致。即所有的观察者都要有一个统一的接口(比如上文中写的update方法,大家的方法都要叫这个名字)。而发布/订阅模式中,订阅者事件的触发不是依靠这样一个接口,而是订阅者通过监听一个特定的消息(这个消息一般包含名称和订阅者所需要的参数)来触发的。可以理解为订阅者监听的不是发布者,而是消息池,只要消息池里有它关心的消息,即触发事件,不管这个消息是谁发布过去的。发布者和订阅者是解耦的。

下面是js中发布/订阅模式的实现,复制粘贴到console里面试一试就明白了:

var pubsub = (function(){

    var q = {}

        topics = {},

        subUid = -1;

    //发布消息

    q.publish = function(topic, args) {

        if(!topics[topic]) {return;}

        var subs = topics[topic],

            len = subs.length;

        while(len--) {

            subs[len].func(topic, args);

        }

        return this;

    };

    //订阅事件

    q.subscribe = function(topic, func) {

        topics[topic] = topics[topic] ? topics[topic] : [];

        var token = (++subUid).toString();

        topics[topic].push({

            token : token,

            func : func

        });

        return token;

    };

    return q;

    //取消订阅就不写了,遍历topics,然后通过保存前面返回token,删除指定元素

})();

//触发的事件

var logmsg = function(topics, data) {

    console.log("logging:" + topics + ":" + data);

}

//监听指定的消息'msgName'

var sub = pubsub.subscribe('msgName', logmsg);

//发布消息'msgName'

pubsub.publish('msgName', 'hello world');

//发布无人监听的消息'msgName1'

pubsub.publish('anotherMsgName', 'me too!');
Javascript 相关文章推荐
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
Apr 21 Javascript
jquery.alert 弹出式复选框实现代码
Jun 15 Javascript
jQuery源码分析-03构造jQuery对象-工具函数
Nov 14 Javascript
JavaScript中数组对象的那些自带方法介绍
Mar 12 Javascript
js无法获取到html标签的属性的解决方法
Jul 26 Javascript
详解jQuery lazyload 懒加载
Dec 19 Javascript
详解.vue文件解析的实现
Jun 11 Javascript
vue移动端弹框组件的实例
Sep 25 Javascript
使用webpack4编译并压缩ES6代码的方法示例
Apr 24 Javascript
Element-UI中关于table表格的那些骚操作(小结)
Aug 15 Javascript
vue改变循环遍历后的数据实例
Nov 07 Javascript
mpvue网易云短信接口实现小程序短信登录的示例代码
Apr 03 Javascript
JavaScript不刷新实现浏览器的前进后退功能
Nov 05 #Javascript
Javascript检查图片大小不要让大图片撑破页面
Nov 04 #Javascript
node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用
Nov 04 #Javascript
node.js中Socket.IO的进阶使用技巧
Nov 04 #Javascript
node.js中的Socket.IO使用实例
Nov 04 #Javascript
Node.js的特点和应用场景介绍
Nov 04 #Javascript
Node.js中的模块机制学习笔记
Nov 04 #Javascript
You might like
深入解析PHP的引用计数机制
2013/06/14 PHP
必须收藏的php实用代码片段
2016/02/02 PHP
PHP依赖注入(DI)和控制反转(IoC)详解
2017/06/12 PHP
使用Git实现Laravel项目的自动化部署
2019/11/24 PHP
jQuery 使用手册(四)
2009/09/23 Javascript
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
2012/08/14 Javascript
使用jquery写个更改表格行顺序的小功能
2014/04/29 Javascript
JavaScript中字符串拼接的基本方法
2015/07/07 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
详解Backbone.js框架中的模型Model与其集合collection
2016/05/05 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
2017/01/11 Javascript
浅谈对Angular中的生命周期钩子的理解
2017/07/31 Javascript
Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)
2019/04/17 Javascript
Vue 数组和对象更新,但是页面没有刷新的解决方式
2019/11/09 Javascript
JS求解两数之和算法详解
2020/04/28 Javascript
[02:58]献给西雅图的情书_高清
2014/05/29 DOTA
python实现每次处理一个字符的三种方法
2014/10/09 Python
Python3中的真除和Floor除法用法分析
2016/03/16 Python
django实现同一个ip十分钟内只能注册一次的实例
2017/11/03 Python
利用Python2下载单张图片与爬取网页图片实例代码
2017/12/25 Python
python读写LMDB文件的方法
2018/07/02 Python
浅析Python与Mongodb数据库之间的操作方法
2019/07/01 Python
如何基于python生成list的所有的子集
2019/11/11 Python
python 实现视频 图像帧提取
2019/12/10 Python
pyx文件 生成pyd 文件用于 cython调用的实现
2021/03/04 Python
美国指甲油品牌:Deco Miami
2017/01/30 全球购物
世界上最全面的草药补充剂和顶级品牌维生素网站:HerbsPro
2019/01/20 全球购物
Kathmandu新西兰官网:新西兰户外运动品牌
2019/07/27 全球购物
介绍一下Java的安全机制
2012/06/28 面试题
教师自我评价范文
2013/12/16 职场文书
《狮子和兔子》教学反思
2014/03/02 职场文书
中秋节国旗下演讲稿
2014/09/05 职场文书
2015年幼儿园学前班工作总结
2015/05/18 职场文书
士兵突击观后感
2015/06/16 职场文书
Python使用BeautifulSoup4修改网页内容
2022/05/20 Python
Go web入门Go pongo2模板引擎
2022/05/20 Golang