javascript设计模式-订阅发布模式(观察者模式)

Sorrow.X      2022-02-12     222

关键词:

var Event = (function() {
            var global = this,    
                Event,
                _default = ‘default‘;

            Event = function() {
                var _create,
                    _listen,
                    _trigger,
                    _remove,
                    _shift = Array.prototype.shift,
                    _unshift = Array.prototype.unshift,
                    namespaceCache = {},
                    each = function(ary, fn) {
                        var ret;
                        for (var i = 0, l = ary.length; i < l; i ++) {
                            var n = ary[i];
                            ret = fn.call(n, i, n);
                        };
                        return ret;
                    };

                _listen = function(key, fn, cache) {
                    if (!cache[key]) {
                        cache[key] = [];
                    };
                    cache[key].push(fn);
                };

                _trigger = function() {
                    var cache = _shift.call(arguments),
                        key = _shift.call(arguments),
                        args = arguments,
                        _self = this,
                        stack = cache[key];

                    if (!stack || !stack.length) return;

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

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

                _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;
                            },

                            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();
                            }, 

                            remove: function(key, fn) {
                                _remove(key, cache, fn);
                            },

                            one: function(key, fn, last) {
                                _remove(key, cache);
                                this.listen(key, fn, last);
                            }

                        };
                    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(‘evt1‘, 1, 2);
        event.trigger(‘evt1‘, 3, 4);    // 都存到offlineStack中去了

        event.listen(‘evt1‘, e1);    // 当有listen监听时,遍历offlineStack中的方法,发给第一次的listen
        event.listen(‘evt1‘, e2);*/

        /*// 先订阅后发布
        event.listen(‘evt1‘, e1);   
        event.listen(‘evt1‘, e2);    // 先订阅的事件都存到cache对象中去了

        event.trigger(‘evt1‘, 1, 2);    // 每次发布,都会遍历cache对象中对象事件名的数组
        event.trigger(‘evt1‘, 3, 4);   */

        /*// 先发布后订阅 listen方法第三个参数可以是last,只有只会去多个trigger中的最后一个
        event.trigger(‘evt1‘, 1, 2);    // 1).
        event.trigger(‘evt1‘, 3, 4);    // 2). 都存到offlineStack中去了

        event.listen(‘evt1‘, e1, ‘last‘);    // 只会收到2).这个trigger*/

        /*// 先订阅后发布再删除然后再发布,会发现evt1事件对象的cache[key]数组中少了e1函数,所以
        // 再次发布只有e2执行了
        event.listen(‘evt1‘, e1);   
        event.listen(‘evt1‘, e2);   

        event.trigger(‘evt1‘, 1, 2);   
        event.remove(‘evt1‘, e1);
        event.trigger(‘evt1‘, 3, 4);*/

        // 订阅的再多,也只使用一个订阅
        /*// 1). 先订阅后发布
        event.one(‘evt1‘, e1);
        event.one(‘evt1‘, e2);    // 会使用这个,因为前一个被删了

        event.trigger(‘evt1‘, 11, 22);    // 所以会执行两次e2函数
        event.trigger(‘evt1‘, 33, 44);*/

        // 2). 先发布后订阅
        /*event.trigger(‘evt1‘, 11, 22);    // 所以会执行两次e2函数
        event.trigger(‘evt1‘, 33, 44);

        event.one(‘evt1‘, e1);    // 会使用这个,因为offlineStack被置为null了
        event.one(‘evt1‘, e2);    // 这个不执行了,需要等到下次trigger才会触发,因为e1从cache中删掉了,加入了e2, 如果后面还有one方法以此类推,会删除上一个监听的函数,添加新的监听函数*/

        // 3). 先发布后订阅 one方法的第三个参数last会只接收最后一个trigger
        event.trigger(‘evt1‘, 11, 22);   
        event.trigger(‘evt1‘, 33, 44);

        event.one(‘evt1‘, e2, ‘last‘);
        event.one(‘evt1‘, e1, ‘last‘);    

 

观察者模式——javascript

观察者模式又被称为发布-订阅模型或消息机制。基本思想是观察者一个静态(或全局)对象,为大家提供三个方法:发布、订阅、取消订阅。想得到消息的订阅者需要通过订阅某些消息,当发布者发布某些消息的时候对应的订... 查看详情

javascript设计模式——观察者模式

观察者模式,又称发布-订阅模式或消息机制,定义了一种依赖关系,解决了主题对象与观察者之间功能的耦合。通过运用观察者模式,可以解决团队开发中的模块间通讯问题,这是模块间解耦的一种可行方案。首先,我们来把... 查看详情

发布-订阅者模式(观察者模式)(代码片段)

发布订阅者模式还有一些好的列子应用可以看看javascript设计模式与开发实践这本书!!!!!一、发布订阅模式是什么发布订阅者模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,... 查看详情

javascript设计模式与开发实践–观察者模式

概述观察者模式又叫发布–订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个目标对象(为了方便理解,以下将观察者对象叫做订阅者,将目标对象叫做发布者)。发布者的状态发生... 查看详情

javascript原生实现观察者模式

观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察着对象。它是由两类对象组成,主题和观察者,主题负责发布事件,... 查看详情

javascript发布订阅者模式和观察者模式及区别(代码片段)

一、发布订阅模式发布订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到状态改变的通知。多方订阅,一方发布,订阅放会收到通知举例:教学楼中... 查看详情

javascript发布订阅者模式和观察者模式及区别(代码片段)

一、发布订阅模式发布订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到状态改变的通知。多方订阅,一方发布,订阅放会收到通知举例:教学楼中... 查看详情

javascript观察者模式

...状态发生该变时,所有依赖于它的对象都将得到通知。在JavaScript中,一般用事件模型来替代传统的观察者模式。   下面是售楼处(发布者)与各看房者(订阅者)的例子:   varevent={    查看详情

发布-订阅模式

...象的状态发生改变,所有依赖他的对象都将得到通知。在javascript开发中,我们一般用事件模型来替代传统的发布-订阅模式。2.Dom事件实际上,只要我们曾经在dom节点上绑定过事件函数,那么我们就曾经使用过发布-订阅模式。docu... 查看详情

javascript设计模式观察者模式

观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。举个例子,... 查看详情

发布-订阅模式

...的状态发生改变时,所有依赖于它的对象都将得到通知。JavaScript开发中我们一般用事件模型来代替传统的发布-订阅模式现实中的发布-订阅模式   小明最近喜欢上吃老北京烧饼,可是到了卖烧饼的地方 查看详情

javascript---设计模式之观察者模式

概念观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。作用支... 查看详情

javascript设计模式与开发实践–观察者模式http://web.jobbole.com/87809/

概述观察者模式又叫发布–订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个目标对象(为了方便理解,以下将观察者对象叫做订阅者,将目标对象叫做发布者)。发布者的状态发生变... 查看详情

javascript手撕前端面试题:寄生组合式继承|发布订阅模式|观察者模式(代码片段)

🧑‍💼个人简介:大三学生,一个不甘平庸的平凡人🍬🖥️NodeJS专栏:Node.js从入门到精通🖥️博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长... 查看详情

设计模式-发布-订阅者模式(代码片段)

1、发布-订阅者设计模式定义定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知观察者模式和发布订阅模式区别观察者模式是由具体目标(发布者/被观察者)调度的,而发... 查看详情

[设计模式]观察者模式与订阅模式

  在读《设计模式》时,观察者模式一直理解为订阅者/发布者,其实这两种模式还是有差异的。  一、观察者模式    相关概念:目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口。具体... 查看详情

观察者模式vs发布-订阅模式

参考技术A差异总结:1.在观察者模式中,观察者(Observer)是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者(Publisher)和订阅者(Subscriber)不知道对方的存在。它们只有通过消息代理(信息... 查看详情

观察者模式与发布订阅模式的区别

观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系... 查看详情