zoukankan      html  css  js  c++  java
  • javascript之观察者模式

    demo1:

    var global = window;
     
    (function(ns, base){
         
        //被观察的对象
        function Observable(){
             
            this.observers = {};
        }   
         
        Observable.prototype = {
             
            //subscribe
            bind: function(name, observer){
                var observers = this.observers[name] || ( this.observers[name] = [] );
                var isbind = observer && observers.indexOf(observer) === -1;
                 
                if(isbind){
                    observers.push(observer);
                }
     
            },
             
            //unsubscribe
            unbind: function(name, observer){
                var observers = this.observers[name],
                    index = observers && observers.indexOf(observer),
                    isunbind = (index !== undefined) && (index > -1);
                     
                if (isunbind ){
                    observers.splice(index, 1);
                }
            },
             
            //publish
            trigger: function (name, args){
                var observers = this.observers[name];
                if(!observers) return;
                 
                for (var i=0; i<observers.length; i++) {
                    observers[i](args);
                }
            }
        };
         
        Observable.fn = Observable.prototype;
        ns.Observable = Observable;
         
    }(global, undefined));
    //测试,Model和View解耦
    (function(){
     
        //UserModel,继承Observable
        function UserModel (id){
            this.id = id;
        }
         
        UserModel.prototype =  new Observable(); 
         
        UserModel.prototype.load = function(){
            //ajax load
            var mode = { name: "jser", id: this.id };
             
            //触发loaded事件
            this.trigger("loaded", { target: this, data: mode } );
         
        }
         
        function UserView(){
            this.render = function(data){
                alert("username: "+ data.name);
            }
        }
         
        var user = new UserModel();
        var view = new UserView();
         
        //添加观察者,当UserMode加载完成调用
        user.bind("loaded", function(event){
            view.render(event.data);
        });
        user.load();
    }());
    

      demo2:

    function Observer() {
        this.fns = [];
    }
    Observer.prototype = {
        subscribe: function (fn) {
            this.fns.push(fn);
        },
        unsubscribe: function (fn) {
            this.fns = this.fns.filter(
                            function (el) {
                                if (el !== fn) {
                                    return el;
                                }
                            }
                        );
        },
        update: function (o, thisObj) {
            var scope = thisObj || window;
            this.fns.forEach(
                            function (el) {
                                el.call(scope, o);
                            }
                        );
        }
    };
    
    //测试
    var o = new Observer;
    var f1 = function (data) {
        console.log('Robbin: ' + data + ', 赶紧干活了!');
    };
    
    var f2 = function (data) {
        console.log('Randall: ' + data + ', 找他加点工资去!');
    };
    
    o.subscribe(f1);
    o.subscribe(f2);
    
    o.update("Tom回来了!")
    
    //退订f1
    o.unsubscribe(f1);
    //再来验证
    o.update("Tom回来了!");
    

      

    if (!Array.prototype.forEach) {
        Array.prototype.forEach = function (fn, thisObj) {
            var scope = thisObj || window;
            for (var i = 0, j = this.length; i < j; ++i) {
                fn.call(scope, this[i], i, this);
            }
        };
    }
    if (!Array.prototype.filter) {
        Array.prototype.filter = function (fn, thisObj) {
            var scope = thisObj || window;
            var a = [];
            for (var i = 0, j = this.length; i < j; ++i) {
                if (!fn.call(scope, this[i], i, this)) {
                    continue;
                }
                a.push(this[i]);
            }
            return a;
        };
    }
    

      demo3:

    //通用代码
    var observer = {
        //订阅
        addSubscriber: function (callback) {
            this.subscribers[this.subscribers.length] = callback;
        },
        //退订
        removeSubscriber: function (callback) {
            for (var i = 0; i < this.subscribers.length; i++) {
                if (this.subscribers[i] === callback) {
                    delete (this.subscribers[i]);
                }
            }
        },
        //发布
        publish: function (what) {
            for (var i = 0; i < this.subscribers.length; i++) {
                if (typeof this.subscribers[i] === 'function') {
                    this.subscribers[i](what);
                }
            }
        },
        // 将对象o具有观察者功能
        make: function (o) { 
            for (var i in this) {
                o[i] = this[i];
                o.subscribers = [];
            }
        }
    };
    var blogger = {
        recommend: function (id) {
            var msg = 'dudu 推荐了的帖子:' + id;
            this.publish(msg);
        }
    };
    
    var user = {
        vote: function (id) {
            var msg = '有人投票了!ID=' + id;
            this.publish(msg);
        }
    };
    
    observer.make(blogger);
    observer.make(user);
    var tom = {
        read: function (what) {
            console.log('Tom看到了如下信息:' + what)
        }
    };
    
    var mm = {
        show: function (what) {
            console.log('mm看到了如下信息:' + what)
        }
    };
    // 订阅
    blogger.addSubscriber(tom.read);
    blogger.addSubscriber(mm.show);
    blogger.recommend(123); //调用发布
    
    //退订
    blogger.removeSubscriber(mm.show);
    blogger.recommend(456); //调用发布
    
    //另外一个对象的订阅
    user.addSubscriber(mm.show);
    user.vote(789); //调用发布
    

      参考地址:1 http://www.cnblogs.com/rentj1/archive/2013/01/08/2851383.html

    http://www.cnblogs.com/TomXu/archive/2012/03/02/2355128.html

  • 相关阅读:
    APUE.3源码编译(Ubuntu16.04)
    《UNIX环境高级编程》(第三版)阅读笔记---2018-5-9
    css回归之用户界面
    css回归之文本
    js回归之字符串
    js回归之BOM
    js回归之事件
    百度前端面试总结
    书单
    剑指offer做题收获之一:补码
  • 原文地址:https://www.cnblogs.com/wangwenfei/p/3049430.html
Copyright © 2011-2022 走看看