zoukankan      html  css  js  c++  java
  • JS模式---发布、订阅模式

    • 发布订阅模式又叫观察者模式,它定义一种一对多的依赖关系,
    • 当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
    document.body.addEventListener('click', function () {
                alert(1);
            }, false);
            document.body.addEventListener('click', function () {
                alert(2);
            }, false);
            document.body.addEventListener('click', function () {
                alert(3);
            }, false);
            document.body.click();

    发布--订阅模式的通用实现

    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);
                    }
                },
                remove: function (key,fn) {
                    var fns = this.clientList[key];
                    if (!fns) {
                        return false;
                    }
                    if (!fn) {
                        fns && (fns.length = 0);
                    } else {
                        for (var i = fns.length-1; i >= 0; i--) {
                            var _fn = fns[i];
                            if (_fn === fn) {
                                
                                fns.splice(i, 1);
                                console.log("删除成功!");
                            }
                        }
                    }
                }
            };
            //给所有对象设置发布-订阅功能
            var installEvent = function (obj) {
                for (var i in event) {
                    obj[i] = event[i];
                }
            };
    
            var salesOffices = {};
            installEvent(salesOffices);
            //订阅
            salesOffices.listen("89cm3",f1= function (price) {
                console.log("价格:"+price);
            });
            salesOffices.listen("120cm3",f2= function (price) {
                console.log("价格:" + price);
            });
            //发布
            salesOffices.trigger("89cm3", 1200000);
            salesOffices.trigger("120cm3", 2200000);
    
            salesOffices.remove("89cm3", f1);
            salesOffices.trigger("89cm3", 1200000);

    • 防止全局命名冲突再重构。
    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 (ary, fn) {
                            var ret;
                            for (var i = 0; i < ary.length; i++) {
                                var n = ary[i];
                                ret = fn.call(n, i, n);
                            }
                            return ret;
                        };
    
                    _listen = function (key,cache,fn) {
                        if (!cache[key]) {
                            cache[key] = [];
                        }
                        cache[key].push(fn);
                    };
    
                    _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] = [];
                            }
                        }
                    };
    
                    _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();
                                }
                            };
                        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;
            })();
  • 相关阅读:
    JavaScript 字符串常用操作
    Redis分布式锁
    CSS布局之-水平垂直居中
    vuejs学习笔记(1)--属性,事件绑定,ajax
    Angular.js学习笔记 (一)
    几年前写的一个支持多数据库切换的设计
    bundle中vim相关快捷键的使用
    使用Bundle进行VIM插件的管理
    javascript代码在线测试
    线程池的创建
  • 原文地址:https://www.cnblogs.com/meiyh/p/6485174.html
Copyright © 2011-2022 走看看