Js實現訂閱發布模式(讓你的代碼寫得賊六)

簡單例子

 var salesoffice = {}; //定義售樓處

     salesoffice.clientList = []; //緩存列表,存放訂閱者的回調函數

    salesoffice.listen = function (key,fn) { //增加訂閱者
        if(!this.clientList[key]){
            this.clientList[key] = [];
        }
        this.clientList[key].push(fn); //訂閱的消息添加進緩存列表
    };

    salesoffice.trigger = function () { //發布消息

        var key = Array.prototype.shift.call(arguments); //取出消息類型
        fns = this.clientList[key];
        if(!fns || fns.length ===0 ){ //如果沒有訂閱改消息,則返回

            return false;
        }
        
        for (var i = 0,fn;fn=fns[i++];){
            fn.apply(this,arguments); //arguments  是發布消息時帶上的參數
        }
    };

//測試例子
    salesoffice.listen('squareMeter88',function (price) {   //小明訂閱消息
        console.log("價格=" + price );
    });


    salesoffice.listen('squareMeter110',function (price) {   //小紅訂閱消息
        console.log("價格=" + price );
    });

    salesoffice.trigger('squareMeter88',2000000);
    salesoffice.trigger('squareMeter110',3000000);

通用實現


    //通用實現

    var event = {
        clientList:[],
        listen : function (key,fn) {
            if(!this.clientList[ key ]){
                this.clientList[ key ] = [];
            }
            this.clientList[key].push(fn);
        },
        trigger:function () {
            var key = Array.prototype.shift.call(arguments),

                fns = this.clientList[ key ];

            if(!fns || fns.length===0){
                return false;
            }

            for (var i=0,fn;fn = fns[i++];){
                fn.apply(this,arguments);
            }
        }
    };

    //在定義一個instalEvent 函數,這個函數可以給所有的對象都動態安裝發布訂閱模式

    var installEvent = function (obj) {
        for (var i in event){
            obj[i] = event[i];
        }
    }

    var salesOffices = {};

    installEvent(salesOffices);

    salesOffices.listen('squareMeter88',function (price) {   //小明訂閱消息
            console.log("價格=" + price );
        });


    salesOffices.listen('squareMeter110',function (price) {   //小紅訂閱消息
            console.log("價格=" + price );
        });

    salesOffices.trigger('squareMeter88',2000000);
    salesOffices.trigger('squareMeter110',3000000);


    //取消訂閱事件

    event.remove = function (key,fn) {
        var fns = this.clientList[ key ];

        if( !fns ){ //如果key對應的消息沒有被人訂閱,則直接返回
            return false;
        }
        if( !fn ){ //如果傳入的具體的回調函數,表示需要取消key對應消息的所有訂閱
            fns && (fns.length=0);
        }else{
            for (var l = fns.length - 1;l >=0;l--){
                var _fn = fns[l];
                if(_fn === fn){
                    fns.splice(l,1); //刪除訂閱者的回調函數
                }
            }
        }
    }

    var salesOffices = {};

    installEvent(salesOffices);

    salesOffices.listen('squareMeter88',fn1 = function (price) {   //小明訂閱消息
        console.log("價格=" + price );
    });


    salesOffices.listen('squareMeter110',fn2 = function (price) {   //小紅訂閱消息
        console.log("價格=" + price );
    });

    salesOffices.remove('squareMeter88',fn1); //刪除小明的訂閱
    salesOffices.trigger('squareMeter110',2000000);

全局的發布--訂閱對象

        //全局的發布--訂閱對象

    var Event = (function () {

        var clientList = {},
            listen,
            trigger,
            remove;

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

        trigger = function () {
            var key = Array.prototype.shift.call(arguments),
                fns = clientList[key];
            if(!fns || fns.length===0){
                return false;
            }

            for (var i =0,fn;fn=fns[i++];){
                fn.apply(this,arguments);
            }

        };
        
        remove = function (key,fn) {
            var fns = clientList[key];
            if(!fns){
                return false
            }

            if(!fn){
                fns && (fns.length=0);
            }else{
                for (var l=fns.length-1;l>=0;l--){
                    var _fn = fns[l];
                    if(_fn===fn){
                        fns.splice(l,1);
                    }
                }
            }
        };
        return {
            listen:listen,
            trigger:trigger,
            remove:remove,
        }
    })();

    Event.listen('squareMeter88',function (price) {
        console.log("價額="+price);
    });

    Event.trigger('squareMeter88',2000000);
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,373評論 25 708
  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,842評論 2 17
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • 潦水盡寒潭流請,煙光凝暮山紫影。 瀲滟將醒,箬枝盤亭,娓娓呢喃泠。 ——莘九
    莘九閱讀 190評論 0 0
  • 上圖是設置的結果,cell四周圓角,陰影為了能明顯設置了綠色。 設置問題:如果都在cell上面設置,圓角和陰影,那...
    djing閱讀 10,855評論 6 9