js-发布订阅

最近在学习js的设计模式,写了个demo.
订阅发布模式如果按数学翻译其实就是.一对多的映射关系.怎么解释呢? 就是一个开关,同时并联几个灯泡(在不同房间),触发的时候,几个灯泡都会得到指令,然后执行发光的行为。

  1. 观察者模式中,目标对象负责维护观察者。发布/订阅模式中发布者不关心订阅者,只负责把消息丢出去就不管了。
  1. 观察者模式中,观察者要提供一个接口,然后当目标对象发生改变时调用此接口使自身状态和目标状态保持一致。即所有的观察者都要有一个统一的接口(比如上文中写的update方法,大家的方法都要叫这个名字)。而发布/订阅模式中,订阅者事件的触发不是依靠这样一个接口,而是订阅者通过监听一个特定的消息(这个消息一般包含名称和订阅者所需要的参数)来触发的。可以理解为订阅者监听的不是发布者,而是消息池,只要消息池里有它关心的消息,即触发事件,不管这个消息是谁发布过去的。发布者和订阅者是解耦的。
<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <style type="text/css">
        ul {
            list-style: none;
        }
        
        li {
            width: 150px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            background: orangered;
        }
        
        li:nth-child(2n-1){
            background: orange;
        }
    </style>

    <body>

        <span>最新发布消息</span> 消息:<span id="msg_num">0</span>
        <ul id="msg">

        </ul>
        <textarea name="" rows="" cols="" id="user_input"></textarea>
        <button id="user_submit">提交</button>
    </body>
    <script src="pubsub.js" type="text/javascript" charset="utf-8"></script>
    <script src="demo01.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        //测试
        Observer.regist('test', function(e) {
            console.log(e.type, e.args.msg);
        });
        Observer.fire('test', {
            msg: 'just for test'
        });
    </script>

</html>
//外观模式 简化获取元素
function $(id) {
    return document.getElementById(id);
}

//追加消息
(function() {
    function addMsgItem(e) {
        var text = e.args.text,
            ul = $('msg'),
            li = document.createElement('li'),
            span = document.createElement('span');
        li.innerHTML = text;
        span.innerHTML = '×',
        span.style.cursor = 'pointer';
        
        //关闭按钮
        span.onclick = function() {
                ul.removeChild(li);
                //发布删除留言消息
                Observer.fire('removeCommentMessage', {
                    num: -1
                });
            }
            //添加删除按钮
        li.appendChild(span);
        //添加留言节点
        ul.appendChild(li);
    }
    //注册添加留言信息
    Observer.regist('addCommentMessage', addMsgItem);

})();

//数量
(function() {
    //更改用户信息数目
    function changeMsgNum(e) {
        //获取数目
        var num = e.args.num;
        $('msg_num').innerHTML = parseInt($('msg_num').innerHTML) + num;
    }
    //注册
    Observer.regist('addCommentMessage', changeMsgNum)
    Observer.regist('removeCommentMessage', changeMsgNum)
})();

//提交消息
(function() {
    //提交信息
    $('user_submit').onclick = function() {
        var text = $('user_input');
        if(text.value === '') {
            return;
        }
        //发布一条消息
        Observer.fire('addCommentMessage', {
            text: text.value,
            num: 1
        });
        text.value = '';
    }

})();
//观察者模式
var Observer = (function() {
    var _message = {};
    return {
        //注册信息接口
        regist: function(type, fn) {
            //如果消息不存在,则创建一个该消息类型
            if(typeof _message[type] === 'undefined') {
                _message[type] = [fn];
            } else {
                _message[type].push(fn);
            }
        },
        //发布信息接口
        fire: function(type, args) {
            //如果该消息没有被注册,返回
            if(!_message[type]) {
                return;
            }
            //定义消息信息
            var events = {
                    type: type,
                    args: args || {}
                },
                i = 0,
                len = _message[type].length;
            for(; i < len; i++) {
                //依次执行注册的消息对应的动作序列
                _message[type][i].call(this, events);
            }
        },
        //移除信息接口
        remove: function(type, fn) {
            //如果消息动作队列存在
            if(_message[type] instanceof Array) {
                //从最后一个消息动作遍历
                var i = _message[type].length - 1;
                for(; i >= 0; i--) {
                    //如果村咋该动作则在消息序列中移除相应动作
                    _message[type][i] === fn && _message[type].splice(i, 1);
                }
            }
        }
    }
})();

新手上路,多多指教

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,657评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,152评论 25 707
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,766评论 0 15
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,763评论 2 17
  • “当某天 再踏进 这校园会是哪片落叶 掉进回忆的流年 表示从一楼到四楼的距离 原来只有三年 ......” 在距离...
    文杏馆长阅读 557评论 3 6