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 相关文章推荐
flash 得到自身url参数的代码
Nov 15 Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
May 15 Javascript
js判断checkbox是否选中个数的方法(超简单)
Aug 19 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
Jan 19 Javascript
js css自定义分页效果
Feb 24 Javascript
Javascript ES6中数据类型Symbol的使用详解
May 02 Javascript
vue axios 简单封装以及思考
Oct 09 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
Dec 05 Javascript
vue实现pdf文档在线预览功能
Nov 26 Javascript
手把手教您实现react异步加载高阶组件
Apr 07 Javascript
TypeScript的安装、使用、自动编译的实现
Apr 10 Javascript
vue-video-player视频播放器使用配置详解
Oct 23 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
ThinkPHP模板输出display用法分析
2014/11/26 PHP
php中json_encode不兼容JSON_UNESCAPED_UNICODE的解决方案
2016/05/31 PHP
PHP上传图片类显示缩略图功能
2016/06/30 PHP
浅谈PHP的数据库接口和技术
2016/12/09 PHP
PHP格式化显示时间date()函数代码
2018/10/03 PHP
javascript 函数速查表
2010/02/07 Javascript
基于jquery的分页控件(C#)
2011/01/06 Javascript
深入理解Javascript动态方法调用与参数修改的问题
2013/12/10 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
基于jQuery实现在线选座之高铁版
2015/08/24 Javascript
JS实现浏览器状态栏文字闪烁效果的方法
2015/10/27 Javascript
不定义JQuery插件 不要说会JQuery
2016/03/07 Javascript
JS监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
2016/08/05 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(上)
2017/04/21 Javascript
node.JS md5加密中文与php结果不一致的解决方法
2017/05/05 Javascript
javaScript和jQuery自动加载简单代码实现方法
2017/11/24 jQuery
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
JS+Canvas实现五子棋游戏
2020/08/26 Javascript
小程序实现tab标签页
2020/11/16 Javascript
Python异常学习笔记
2015/02/03 Python
深入理解Python中的*重复运算符
2017/10/28 Python
python tensorflow学习之识别单张图片的实现的示例
2018/02/09 Python
对python pandas 画移动平均线的方法详解
2018/11/28 Python
Python3实现的反转单链表算法示例
2019/03/08 Python
Python学习笔记之读取文件、OS模块、异常处理、with as语法示例
2019/06/04 Python
使用Python检测文章抄袭及去重算法原理解析
2019/06/14 Python
Django结合ajax进行页面实时更新的例子
2019/08/12 Python
Python Sympy计算梯度、散度和旋度的实例
2019/12/06 Python
python连接mongodb集群方法详解
2020/02/13 Python
Python3合并两个有序数组代码实例
2020/08/11 Python
Python3.9新特性详解
2020/10/10 Python
HTML5 解析规则分析
2009/08/14 HTML / CSS
狼和鹿教学反思
2014/02/05 职场文书
大学班级学风建设方案
2014/05/01 职场文书
清明节主题班会
2015/08/14 职场文书
Python实现学生管理系统并生成exe可执行文件详解流程
2022/01/22 Python