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 相关文章推荐
Javascript下IE与Firefox下的差异兼容写法总结
Jun 18 Javascript
js控制的回到页面顶端goTop的代码实现
Mar 20 Javascript
JS实现先显示大图后自动收起显示小图的广告代码
Sep 04 Javascript
Node.js与Sails ~项目结构与Mvc实现及日志机制
Oct 14 Javascript
fullCalendar中文API官方文档
Feb 07 Javascript
angular之ng-template模板加载
Nov 09 Javascript
使用JavaScript实现node.js中的path.join方法
Aug 12 Javascript
JS使用Date对象实时显示当前系统时间简单示例
Aug 23 Javascript
JavaScript Canvas实现验证码
Aug 02 Javascript
Vue高版本中一些新特性的使用详解
Sep 25 Javascript
详解jQuery设置内容和属性
Apr 11 jQuery
js中Object.create实例用法详解
Oct 05 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类的静态(static)方法和静态(static)变量使用介绍
2012/02/19 PHP
用Jquery实现多级下拉框无刷新的联动
2010/12/22 Javascript
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
2011/03/10 Javascript
使用Post提交时须将空格转换成加号的解释
2013/01/14 Javascript
JS判断不同分辨率调用不同的CSS样式文件实现思路及测试代码
2013/01/23 Javascript
jQuery实现id模糊查询的小例子
2013/03/19 Javascript
关于jquery css的使用介绍
2013/04/18 Javascript
深入理解JavaScript中的对象
2015/06/04 Javascript
JavaScript 封装一个tab效果源码分享
2015/09/15 Javascript
js实现文件上传表单域美化特效
2015/11/02 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
2016/04/13 Javascript
浅谈JavaScript中变量和函数声明的提升
2016/08/09 Javascript
JavaScript实现时钟滴答声效果
2017/01/29 Javascript
JavaScript实现替换字符串中最后一个字符的方法
2017/03/07 Javascript
jQuery zTree树插件动态加载实例代码
2017/05/11 jQuery
Vue常用的几个指令附完整案例
2018/11/06 Javascript
angular4笔记系列之内置指令小结
2018/11/09 Javascript
JS写滑稽笑脸运动效果
2020/05/28 Javascript
Python字符串和文件操作常用函数分析
2015/04/08 Python
python3+PyQt5使用数据库窗口视图
2018/04/24 Python
python 统计列表中不同元素的数量方法
2018/06/29 Python
Pandas读取MySQL数据到DataFrame的方法
2018/07/25 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
pytorch对可变长度序列的处理方法详解
2018/12/08 Python
Python依赖包整体迁移方法详解
2019/08/15 Python
python 一维二维插值实例
2020/04/22 Python
python调用API接口实现登陆短信验证
2020/05/10 Python
HTML5 audio标签使用js进行播放控制实例
2015/04/24 HTML / CSS
Viking Direct爱尔兰:办公用品和家具
2019/11/21 全球购物
巴西备受欢迎的服装和生活方式品牌:FARM Rio
2020/02/04 全球购物
伦敦奥运会口号
2014/06/13 职场文书
大学生违纪检讨书300字
2014/10/25 职场文书
掌握这项技巧,一年阅读300本书不是梦
2019/09/12 职场文书
浅谈resultMap的用法及关联结果集映射
2021/06/30 Java/Android
Win11运行cmd提示“请求的操作需要提升”的两种解决方法
2022/07/07 数码科技
MyBatis在注解上使用动态SQL方式(@select使用if)
2022/07/07 Java/Android