发布——订阅模式

一、什么是发布——订阅模式

        发布订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将得到通知

二、发布——订阅模式的作用

    1、用于异步编程,取代传递回调函数的方案

    2、让两个对象松耦合地联系在一起,一个对象不再显式地调用另一个对象的接口

三、如何实现

    1、三要素

        发布者;

        缓存列表;

        订阅者的回调;

    2、实现代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>监听者模式</title>
</head>
<body>


<script type="text/javascript">
    var Event = (function () {
        var /*global = this,*/
            Event,
            _default = "default";

        Event = function () {
            var _listen,
                _trigger,
                _remove,
                // _slice = Array.prototype.slice,
                _shift = Array.prototype.shift,
                _unshift = Array.prototype.unshift,
                nameSpaceCache = {},
                _create,
                // find,
                each = function (arr, fn) {
                    var ret;
                    for (var i = 0, l = arr.length; i < l; i++) {
                        var n = arr[i];
                        ret = fn.call(n, i, n);
                    }
                    return ret;
                };
            _listen = function (key, fn, cache) {
                if (!cache[key]) {
                    cache[key] = [];
                }
                cache[key].push(fn);
            };

            _remove = function (key, cache, fn) {
                if (cache[key]) {
                    if (fn) {
                        for (var i =0,l=cache[key].length; i < l; i++) {
                            if (cache[key][i] === fn) {
                                cache[key].splice(i, 1);
                                i--;
                            }
                        }
                    } else {
                        cache[key] = [];
                    }
                }
            };

            _trigger = function () {
                var cache = _shift.call(arguments),
                    key = _shift.call(arguments),
                    args = arguments,
                    _self = this,
                    ret,
                    stack = cache[key];
                if (!stack || !stack.length) {
                    return;
                }

                return each(stack, function () {
                    return this.apply(_self, args);
                })
            };

            _create = function (namespace) {
                var namespace = namespace || _default;
                var cache = {},
                    offlineStack = [],//离线事件
                    ret = {
                        listen: function (key,fn,last) {
                            _listen(key,fn,cache);
                            if(offlineStack==null){
                                return;
                            }
                            if(last==="last"){
                                offlineStack.length && offlineStack.pop()();
                            }else{
                                each(offlineStack,function(){
                                    this();
                                })
                            }
                            offlineStack=null;
                        },
                        one:function(key,fn,last){
                            _remove(key,cache);
                            this.listen(key,fn,last);

                        },
                        remove:function(key,fn){
                            _remove(key,cache,fn);
                        },
                        trigger:function(){
                            var fn,
                                args,
                                _self=this;
                            _unshift.call(arguments,cache);
                            args=arguments;
                            fn=function(){
                                return _trigger.apply(_self,args);
                            };

                            if(offlineStack){
                                return offlineStack.push(fn);
                            }

                            return fn();
                        }
                    };
                console.log(nameSpaceCache);

                return namespace?
                    (nameSpaceCache[namespace]?nameSpaceCache[namespace]:
                    nameSpaceCache[namespace]=ret)
                    :ret;
            };
            return{
                create:_create,
                one:function(key,fn,last){
                    var event=this.create();
                    event.one(key,fn,last);
                },
                remove:function(key,fn){
                    var event=this.create();
                    event.remove(key,fn);
                },
                listen:function(key,fn,last){
                    var event=this.create();
                    event.listen(key,fn,last);

                },
                trigger:function(){
                    var event=this.create();
                    event.trigger.apply(this,arguments);
                }
            }

        }();
        return Event;
    })()


    /**
     * 先发布后订阅
     */
    Event.trigger('click',1);
    Event.listen('click',function(a){
        console.log(a);
    })


    /**
     * 使用命名空间
     */
    Event.create('nameSpace1').listen('click',function(a){
        console.log(a);
    });
    Event.create('nameSpace1').trigger('click',1);

    Event.create('nameSpace2').listen('click',function(a){
        console.log(a);
    });
    Event.create('nameSpace1').trigger('click',2);

</script>
</body>
</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值