JavaScript之观察者模式

观察者模式也叫发布订阅模式!,为了解决主体对象与观察者之间功能的耦合。
定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖对象都会收到通知自动更新。

观察者模式主要分为三个步骤:注册、发布、移除。我们一个一个步骤来实现。
我们定义一个容器,再用闭包包起来,防止污染全局变量,里面存放这些方法,以及要观察的事件。

详细解释看注解

 //防止信息队列暴露而被慕改或影响到其他变量
 var Observer = (function () {
     var _messages = {};
     return {
         //注册信息接口
         regist: function (type, fn) {
             //如果此信息不存在则应该创建一个该消息类型
             if (typeof _messages[type] === 'undefined') {
                 //将动作推入到该信息对应的动作执行队列中
                 _messages[type] = [fn];

             } else {
                 _messages[type].push(fn);
             }
         },
         //发布信息接口
         fire: function (type, args) {
             //如果该小心没有被注册,则返回
             if (!_messages[type])
                 return;
             //定义小心信息
             var events = {
                     type: type, //消息类型
                     args: args || {} //消息携带数据
                 },
                 i = 0, //消息动作循环变量
                 len = _messages[type].length; //消息动作长度
             //遍历消息动作
             for (; i < len; i++) {
                 //依次执行注册的消息对应的动作序列
                 _messages[type][i].call(this, events);
             }
         },
         //移除信息接口
         remove: function (type, fn) {
             //如果消息动作队列存在
             if (_message[type] instanceof Array) {
                 //从最后一个消息动作遍历
                 var i = _message[type].length - 1;
                 for (; i >= 0; i--) {
                     //如果存在该动作在消息动作序列中移除相应动作
                     _messages[type][i] === fn && _messages[type].splice(i, 1);
                 }
             }
         }
     }
 })();

上面就是我们定义好的观察者,当我们想要订阅发布某些实例的时候直接调用即可。
接着我们结合实例来看一下这是怎么使用的,例如我们做一个留言并统计浏览数量的小功能

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div>
        <div>
            用户的数量
            <span id="msg_num">0</span>
        </div>
        <ul id="msg">

        </ul>
        <input type="text" id="user_input" />
        <button id="user_submit">提交</button>

    </div>




    <script>
        //防止信息队列暴露而被慕改或影响到其他变量
        var Observer = (function () {
            var _messages = {};
            return {
                //注册信息接口
                regist: function (type, fn) {
                    //如果此信息不存在则应该创建一个该消息类型
                    if (typeof _messages[type] === 'undefined') {
                        //将动作推入到该信息对应的动作执行队列中
                        _messages[type] = [fn];

                    } else {
                        _messages[type].push(fn);
                    }
                },
                //发布信息接口
                fire: function (type, args) {
                    //如果该小心没有被注册,则返回
                    if (!_messages[type])
                        return;
                    //定义小心信息
                    var events = {
                            type: type, //消息类型
                            args: args || {} //消息携带数据
                        },
                        i = 0, //消息动作循环变量
                        len = _messages[type].length; //消息动作长度
                    //遍历消息动作
                    for (; i < len; i++) {
                        //依次执行注册的消息对应的动作序列
                        _messages[type][i].call(this, events);
                    }
                },
                //移除信息接口
                remove: function (type, fn) {
                    //如果消息动作队列存在
                    if (_message[type] instanceof Array) {
                        //从最后一个消息动作遍历
                        var i = _message[type].length - 1;
                        for (; i >= 0; i--) {
                            //如果存在该动作在消息动作序列中移除相应动作
                            _messages[type][i] === fn && _messages[type].splice(i, 1);
                        }
                    }
                }
            }
        })();


        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');
                span.innerHTML = " 关闭"

                li.innerHTML = text;

                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 = '';
            }
        })();
    </script>
</body>

</html>

在这个例子中可以看出我们将每个模块抽离了出来,互不关系,完美解决模块间耦合功能。
其使用什么广泛,适用于关联于某些行为场景,并触发一系列事件。例如用来发布消息推送、点击事件侦听等等。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值