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 相关文章推荐
js中的window.open返回object的错误的解决方法
Aug 15 Javascript
javascript 短路法代码精简
Aug 20 Javascript
JSON 教程 json入门学习笔记
Sep 22 Javascript
JavaScript/jQuery 表单美化插件小结
Feb 14 Javascript
jquery高效反选具体实现
May 05 Javascript
JS 获取滚动条高度示例代码
Oct 24 Javascript
鼠标拖拽移动子窗体的JS实现
Feb 25 Javascript
使用BootStrap和Metroui设计的metro风格微网站或手机app界面
Oct 21 Javascript
利用浮层使select不可选的实现方法
Dec 03 Javascript
vue.js中ref及$refs的使用方法解析
Oct 08 Javascript
js new Date()实例测试
Oct 31 Javascript
JS 5种遍历对象的方式
Jun 16 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&java(二)
2006/10/09 PHP
Yii实现Command任务处理的方法详解
2016/07/14 PHP
PHP简单实现数字分页功能示例
2016/08/24 PHP
PHP实现自动发送邮件功能代码(qq 邮箱)
2017/08/18 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
2017/09/26 PHP
laravel框架实现去掉URL中index.php的方法
2019/10/12 PHP
jquery EasyUI的formatter格式化函数代码
2011/01/12 Javascript
jquery中each遍历对象和数组示例
2014/08/05 Javascript
JQuery显示隐藏页面元素的方法总结
2015/04/16 Javascript
利用jQuery设计一个简单的web音乐播放器的实例分享
2016/03/08 Javascript
bootstrap daterangepicker汉化以及扩展功能
2017/06/15 Javascript
AngularJS使用ng-repeat遍历二维数组元素的方法详解
2017/11/11 Javascript
jquery中有哪些api jQuery主要API
2017/11/20 jQuery
浅谈在react中如何实现扫码枪输入
2018/07/04 Javascript
vue+elementUI实现表格关键字筛选高亮
2020/10/26 Javascript
微信小程序 点击切换样式scroll-view实现代码实例
2019/10/11 Javascript
Vue中用JSON实现刷新界面不影响倒计时
2020/10/26 Javascript
SpringBoot+Vue 前后端合并部署的配置方法
2020/12/30 Vue.js
[06:11]2014DOTA2国际邀请赛 专访团结一心的VG战队
2014/07/21 DOTA
Python将文本去空格并保存到txt文件中的实例
2018/07/24 Python
对pytorch网络层结构的数组化详解
2018/12/08 Python
OpenCV 轮廓检测的实现方法
2019/07/03 Python
Python彻底删除文件夹及其子文件方式
2019/12/23 Python
关于Python Tkinter Button控件command传参问题的解决方式
2020/03/04 Python
python简单实现9宫格图片实例
2020/09/03 Python
最新PyCharm从安装到PyCharm永久激活再到PyCharm官方中文汉化详细教程
2020/11/17 Python
css3实现波纹特效、H5实现动态波浪效果
2018/01/31 HTML / CSS
师范应届生教师求职信
2013/11/05 职场文书
电厂厂长岗位职责
2014/01/02 职场文书
电子银行营销方案
2014/02/22 职场文书
警校毕业生自我评价
2014/04/06 职场文书
大学新闻系自荐书
2014/05/31 职场文书
手机被没收的检讨书
2014/10/04 职场文书
2015年卫生院健康教育工作总结
2015/07/24 职场文书
2015年库房管理工作总结
2015/10/14 职场文书
《宝可梦》动画制作25周年到来 官方发布特别纪念视频
2022/04/01 日漫