JavaScript实现的发布/订阅(Pub/Sub)模式
时间 2016-05-02 18:47:58  GiantMing's blog
原文  http://giantming.net/javascriptshi-xian-de-fa-bu-ding-yue-pub-sub-mo-shi/
主题 JavaScript 观察者模式
前段时间看了一下发布订阅者模式(也叫观察者模式),今天看<基于mvc的JavaScript的富应用开发>又看到了它,这个设计模式是非常有用的,正好写篇博客来分享一下.(标点符号我是不管的,别打我..) 一些前端MVVM框架就是用的观察者模式实现是双向绑定 先上维基百科看看: 观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。 <基于mvc的JavaScript的富应用开发>上给的解释: 发布/订阅模式(Pub/Sub)是一种消息模式,它有 两个参与者 : : 发布者和订阅者 。发布者向 某个信道发布一条消息,订阅者绑定这个信道,当有消息发布至信道时就会 接收到一个通知。最重要的一点是, 发布者和订阅者是完全解耦的,彼此并不知晓对方 的存在。两者仅仅共享一个信道名称。 理解起来很简单: 我去书报亭订了一份报纸,当他把报纸送给我了,我就去领了看. 这里,我就变成了 订阅者 ,报亭就是 发布者 ,当报纸送到的时候(状态发生改变,通知订阅者),我就去领了看(做一些操作) 废话说完了,我觉得我需要写一个,不然读者都以为我在吹牛,所以,装逼装到位,我就假装写一个吧(如有雷同纯属巧合) 一个发布者应该有三个主要的方法: 订阅,发布,退订. 先来写订阅: var PubSub = {};  
var eventObj = {};  
PubSub.subscribe = function(event, fn) {  
     eventObj[event] = fn;
}
再来写个发布: PubSub.publish = function(event) {  
    if (eventObj[event]) eventObj[event]();
}
最后写一个退订: PubSub.off = function(event, fn) {  
    if (eventObj[event]) eventObj[event] = null;
}
我们来整理一下代码用闭包隐藏eventObj这个对象: var PubSub = (function() {  
    var eventObj = {};
    return {
        subscribe: function(event, fn) {
            eventObj[event] = fn;
        },
        publish: function(event) {
            if (eventObj[event]) eventObj[event]();
        },
        off: function(event) {
            if (eventObj[event]) delete eventObj[event];
        }
    }
}());
用一下试试试能不能跑: PubSub.subscribe('event', function() {  
    console.log('event release');
});
PubSub.publish('event'); // 'event release'  
OK it work!! 这绝对是最简单无脑的观察者模式的实现了,你以为这就完了吗? 这样..这个一个事件只能绑定一个操作,并且取消订阅把整个事件都删除掉了,这样就不是很好了,我们应该写一个支持一个事件绑定多个操作的,并且退订时是退订一个事件上的一个操作,而不是删除整个事件 再来: 一个事件绑定多个操作,我们应该用一个数组把操作保存起来,发布时按订阅顺序执行,退订时删除对应的数组元素就好. var PubSub = (function() {  
    var queue = {};
    var subscribe = function(event, fn) {
        if (!queue[event]) queue[event] = [];
        queue[event].push(fn);
    }
    var publish = function(event) {
        var eventQueue = queue[event],
            len = eventQueue.length;
        if (eventQueue) {
            eventQueue.forEach(function(item, index) {
                item();
            });
        }
    }
    var off = function(event, fn) {
        var eventQueue = queue[event];
        if (eventQueue) {
            queue[event] = eventQueue.filter(function(item) {
                return item !== fn;
            });
        }
    }
    return {
        subscribe: on,
        publish: emit,
        off: off
    }
}());
以上就是一个简单的观察者模式的实现了. example: function first() {  
    console.log('event a publish first');
}
PubSub.subscribe('a', first);  
PubSub.subscribe('a', function() {  
    console.log('event a publish second');
});
PubSub.publish('a'); // event a emit first, event a emit second PubSub.off('a', first);  
PubSub.publish('a');  //event a emit second  
以上.

JavaScript实现的发布/订阅(Pub/Sub)模式的更多相关文章

  1. Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 如何实现发布--订阅模式? 发布---订阅模式的代码封装 如何取消订阅事件? 全局--发布订阅对象代码封装 理解模块间通信 回到 ...

  2. [转] Javascript中理解发布--订阅模式

    发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 现实生活中的发布- ...

  3. [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  4. 【转】Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时 ...

  5. javascript中的发布订阅模式与观察者模式

    这里了解一下JavaScript中的发布订阅模式和观察者模式,观察者模式是24种基础设计模式之一. 设计模式的背景 设计模式并非是软件开发的专业术语,实际上设计模式最早诞生于建筑学. 设计模式的定义是 ...

  6. JavaScript设计模式(发布订阅模式)

    发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在JavaScript开发中,我们一般用事件模型来替代传统的发布—订阅模式 ...

  7. Javascript设计模式之发布-订阅模式

    简介 发布-订阅模式又叫做观察者模式,他定义了一种一对多的依赖关系,即当一个对象的状态发生改变的时候,所有依赖他的对象都会得到通知. 回忆曾经 作为一名前端开发人员,给DOM节点绑定事件可是再频繁不过 ...

  8. javascript 自定义事件 发布-订阅 模式 Event

    * javascript自定义事件 var myEvent = document.createEvent("Event"); myEvent.initEvent("myE ...

  9. javaScript设计模式:发布订阅模式

    发布订阅模式的思想是在观察者模式的基础上演变而来,在观察者模式中客户端监听到对象某个行为就触发对应任务程序.而在发布订阅模式中依然基于这个核心思想,所以有时候也会将两者认为是同一种设计模式.它们的不同 ...

随机推荐

  1. Spark2.0集成Hive操作的相关配置与注意事项

    前言 已完成安装Apache Hive,具体安装步骤请参照,Linux基于Hadoop2.8.0集群安装配置Hive2.1.1及基础操作 补充说明 Hive中metastore(元数据存储)的三种方式 ...

  2. 初学Java 二维数组找出最近的两个点

    import java.util.Scanner; public class FindNearestPoints { public static void main(String[] args) { ...

  3. ps:新建Photoshop图像

    从现在起我们开始正式地接触Photoshop,为了保证大家的快捷键设置与教程内容一致.请确认Photoshop的快捷键设置是默认值.可从菜单[编辑 键盘快捷键]打开快捷键设置,在组选项里面选择“Pho ...

  4. bzoj1706 [usaco2007 Nov]relays 奶牛接力跑 矩阵快速幂

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1706 题解 换个方法定义矩阵乘法:先加再取 \(\min\). 对于一个 \(n\times ...

  5. jmeter性能工具 之 cookie 管理器 (二)

    上一篇主要介绍了jmeter 的基本使用方法,编写了登陆脚本,这一篇在登陆基础上,进行充值操作. 问:什么时候需要用到cookied 管理器? 答:需要登陆信息时,如果充值,提现,淘宝的下单,添加到购 ...

  6. 怎么在tensorflow中打印graph中的tensor信息

    from tensorflow.python import pywrap_tensorflow import os checkpoint_path=os.path.join('./model.ckpt ...

  7. What are the differences between an LES-SGS model and a RANS based turbulence model?

    The biggest difference between LES and RANS is that, contrary to LES, RANS assumes that \(\overline{ ...

  8. AndroidManifest.xml里加入不同package的component (Activity、Service里android:name里指定的值一般为句号加类名),可以通过指定完全类名(包名+类名)来解决

    我们都知道对于多个Activity如果在同一个包中,在Mainfest中可以这样注册 <span style="font-size: small;"><?xml  ...

  9. nginx之访问静态文件

    如何配置nginx,访问服务器上的静态文件? 1.在目录/data/interface_test下创建静态文件queryAppData.json,内容如下: 如何访问该文件呢? 2.修改/usr/lo ...

  10. php key()函数 语法

    php key()函数 语法 作用:返回数组内部指针当前指向元素的键名.大理石构件支架 语法:key(array) 参数: 参数 描述 array 必需.规定要使用的数组. 说明:返回数组内部指针当前 ...