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 相关文章推荐
基于JQuery的访问WebService的代码(可访问Java[Xfire])
Nov 19 Javascript
js判断运行jsp页面的浏览器类型以及版本示例
Oct 30 Javascript
javascript中sort() 方法使用详解
Aug 30 Javascript
JavaScript 性能优化小结
Oct 12 Javascript
javascript实现动态标签云
Oct 16 Javascript
JavaScript实现鼠标点击导航栏变色特效
Feb 08 Javascript
AngularJS service之select下拉菜单效果
Jul 28 Javascript
js中document.write和document.writeln的区别
Mar 11 Javascript
vue数组对象排序的实现代码
Jun 20 Javascript
vue.js实现插入数值与表达式的方法分析
Jul 06 Javascript
Element-ui中元素滚动时el-option超出元素区域的问题
May 30 Javascript
React冒泡和阻止冒泡的应用详解
Aug 18 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+xml结合Ajax实现点赞功能完整实例
2015/01/30 PHP
详解配置 Apache 服务器支持 PHP 文件的解析
2017/02/15 PHP
Laravel框架模型的创建及模型对数据操作示例
2019/05/07 PHP
laravel ORM关联关系中的 with和whereHas用法
2019/10/16 PHP
PHP常用函数之格式化时间操作示例
2019/10/21 PHP
PHP中的输出echo、print、printf、sprintf、print_r和var_dump的示例代码
2020/12/01 PHP
原生js实现移动开发轮播图、相册滑动特效
2015/04/17 Javascript
JavaScript设置表单上传时文件个数的方法
2015/08/11 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
2016/01/18 Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
2018/02/08 Javascript
vuex 的简单使用
2018/03/22 Javascript
jquery实现轮播图特效
2020/04/12 jQuery
Python列表推导式的使用方法
2013/11/21 Python
Python中使用urllib2防止302跳转的代码例子
2014/07/07 Python
在Python的setuptools框架下生成egg的教程
2015/04/13 Python
初步剖析C语言编程中的结构体
2016/01/16 Python
python 实现网上商城,转账,存取款等功能的信用卡系统
2016/07/15 Python
win系统下为Python3.5安装flask-mongoengine 库
2016/12/20 Python
python爬虫 使用真实浏览器打开网页的两种方法总结
2018/04/21 Python
pip install urllib2不能安装的解决方法
2018/06/12 Python
Django contenttypes 框架详解(小结)
2018/08/13 Python
python 调用pyautogui 实时获取鼠标的位置、移动鼠标的方法
2019/08/27 Python
Python实现仿射密码的思路详解
2020/04/23 Python
keras的三种模型实现与区别说明
2020/07/03 Python
Keras 在fit_generator训练方式中加入图像random_crop操作
2020/07/03 Python
使用pandas读取表格数据并进行单行数据拼接的详细教程
2021/03/03 Python
初中生自我鉴定
2014/02/04 职场文书
歌唱比赛主持词
2014/03/18 职场文书
电视购物广告词
2014/03/19 职场文书
幼儿园保育员岗位职责
2014/04/13 职场文书
《灰椋鸟》教学反思
2014/04/27 职场文书
花田少年史观后感
2015/06/16 职场文书
尊师重教主题班会
2015/08/14 职场文书
Nginx快速入门教程
2021/03/31 Servers
MySQL 那些常见的错误设计规范,你都知道吗
2021/07/16 MySQL
threejs太阳光与阴影效果实例代码
2022/04/05 Javascript