zoukankan      html  css  js  c++  java
  • 模式学习⑧--观察者模式

    var publisher = {
    
            // 一个由数组组成的集合
            subscribers : {
                any : []// 事件类型: 订阅者(subsribes)
            },
    
            // 将订阅者加入数组 // subscribers : { any : [fn], weekly : [fn], monthly : [fn]}
            subscribe : function(fn, type){
                type = type || 'any';
                if(typeof this.subscribers[type] === "undefined"){
                    console.log("this ::",this);
                    this.subscribers[type] = [];
                }
                this.subscribers[type].push(fn); //any ->  [fn] /  weekly -> [fn] / monthly -> [fn]
                // console.log("this.subscribers[type]     ",this.subscribers["any"]);
                // console.log("this.subscribers[type]     ",this.subscribers["monthly"]);
            },
    
            // 从数组中删除订阅者
            unsubscribe : function(fn, type){
                this.visitSubscribers('unsubscribe', fn, type);
            },
    
            // 遍历订阅者并调用它们订阅时提供的方法
            publish : function(publication, type){
                this.visitSubscribers('publish', publication, type);
            },
            visitSubscribers : function(action, arg, type){ // action = 'publish' ,arg = publication = "big news today"
                var pubtype = type || 'any',
                    subscribers = this.subscribers[pubtype],// subscribe得到的数组[fn]
                    i,
                    max = subscribers.length;
                for(i = 0; i < max; i++){
                    if(action === 'publish'){
                        // console.log("arg:", arg)
                        subscribers[i](arg); // 执行 fn()
                    }else{  
                        if(subscribers[i] === arg){
                            subscribers.splice(i, 1);
                        }
                    }
                }
            }
        };
    
        function makePublisher(o){
            var i;
            for(i in publisher){
                if(publisher.hasOwnProperty(i) && typeof publisher[i] === "function"){
                    o[i] = publisher[i];
                }
            }
            o.subscribers = {any : []};
        }
    
        // 实现paper对象,它所能做的就是发布日报和月刊
        var paper = {
            daily : function(){
                this.publish("big news today");
            },
            weekly : function(){
                this.publish("big news in a week", 'weekly');
            },
            monthly : function(){
                this.publish("interesting analysis", "monthly");
            }
        };
    
        // 将paper对象变成发布者:
        makePublisher(paper);
    
        // 订阅者对象joe
        var joe = {
            drinkCoffee : function(paper){
                console.log("Just read " + paper);
            },
            dinner : function(weekly){
                console.log("Just read " + weekly);
            },
            sundayPreNap : function(monthly){
                console.log("About to fall asleep reading this " + monthly);
            }
        };
    
        // 现在,paper注册joe
        paper.subscribe(joe.drinkCoffee);
        paper.subscribe(joe.dinner, 'weekly');
        paper.subscribe(joe.sundayPreNap, 'monthly');
    
        paper.daily();
        paper.weekly();
        paper.monthly();
        paper.daily();
        paper.daily();
        paper.monthly();
    
        makePublisher(joe);
        joe.tweet = function(msg){
            this.publish(msg);
        };
    
        paper.readTweets = function(tweet){
            console.log("Call big meeting! Someone " + tweet);
        };
        joe.subscribe(paper.readTweets);
    
        joe.tweet("hates the paper today");
       joe.tweet("loves the paper today");

    说明:

      1. 将发布publish作为单独的Object,再借用Makepublisher()方法, 可以使得paper, joe, xx , oo 都能成为发布者。

      2. subscribers 在这里是类似于 { any : [fn], weekly : [fn], monthly : [fn]} 这样的object. 里面的 any weekly monthly 都是type类型。(any是默认的)

      3. A - MakePublisher(xx), 让xx成为发布者

        B - xx.subscribe(oo); oo 可以是另一个观察者的方法-既是订阅

         C - 发布:调用publish()方法

      4. 其中的访问订阅者visitSubscribers ,用来 -发布/删除- 订阅者  

        publication 是发布的内容,subscribers = this.subscribers[pubtype] - 获取发布者的type对应的 订阅者要执行的函数 相当于 1 中的[fn],  subScribers[i](arg) ,但其实这里的arg又是引用的发布者的内容, 就是根据发布的类型执行了订阅者本身的函数(参数是发布的内容)。 

      5. A 可以给 B发布,B也可以给A发布。

  • 相关阅读:
    mysql中GROUP_CONCAT的使用
    sublime text3 配置
    dede自定义标签
    mysql索引
    mysql5.5以上开启慢查询
    mysql定位慢查询
    mysql5.5以上my.ini中设置字符集
    mysql数据库的优化
    win下Apache2.4的下载与安装
    PHP Warning: PHP Startup: in Unknown on line 0
  • 原文地址:https://www.cnblogs.com/chuyu/p/3499569.html
Copyright © 2011-2022 走看看