javascript设计模式-(六)

函数节流

一种限制函数被频繁调用的解决方案,比如我们在 window.onresize 事件中要打印当前的浏览器窗口大小,在我们通过拖曳来改变 窗口大小的时候,打印窗口大小的工作 1秒钟进行了 10次。而我们实际上只需要 2次或者 3次。 这就需要我们按时间段来忽略掉一些事件请求,比如确保在 500ms内只打印一次。很显然,我们 可以借助 setTimeout 来完成这件事情。

    var throttle=function(fn,interval){
        var _self=fn,
            timer,
            firstTime=true;
        return function(){
            var args=arguments,
                _me=this;

            if(firstTime){
                _self.apply(_me,args);
                return firstTime=false;
            }

            if(timer){
                return false;
            }

            timer=setTimeout(function(){
                clearTimeout(timer);
                timer=null;
                _self.apply(_me,args);
            },interval||500);
        };
    };

        window.onresize=throttle(function(){
            console.log(1);
        },500);
发布-订阅模式

发布 — 订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知。在 JavaScript开发中,我们一般用事件模型 来替代传统的发布 — 订阅模式。

简单的 发布-订阅模式

以购房为例,我们购房一般会先去了解房屋的信息,比如房价,房屋的地址,平方等等信息,我们可以主动地去获取这些信息,在现实生活中,我们主动的方式有去售楼部咨询,也可以去网上查询信息。现在假设我们想买一套房,但是价格太高,我们想等他降一降房价再去买(PS:基本不可能),又或者现在这个户型的房子卖光了,但是过一段时间还有有这种户型的房子出售时,我们怎么知道这行房屋信息的变化呢?你可以主动的去获取这些信息,但是我们主动去获取这些信息会花费我我们太多的时间,所以我们可以这样,我们留下自己的联系信息给售房部的人,让售房部的人在信息变化时,主动通知我们,这样我们就可以省掉许多时间了,这就是发布-订阅模式在现实中的一个简单的例子。

    //自定义事件
    var salesOffices={};            //售楼处

    salesOffices.clientList=[];     //缓存列表,存放订阅者的回调函数

    salesOffices.listen=function(fn){
        this.clientList.push(fn);
    };

    salesOffices.trigger=function(){
        for(var i=0,fn;fn=this.clientList[i++];){
            fn.apply(this,arguments);
        }
    }

    //测试
    salesOffices.listen(function(price,sq){
        console.log("小明的订阅");
        console.log("价格:"+price);
        console.log("平方数:"+sq);
    });

    salesOffices.listen(function(price,sq){
        console.log("小红的订阅");
        console.log("价格:"+price);
        console.log("平方数:"+sq);
    });

    salesOffices.trigger(3000,88);

    console.log("");
    console.log("");
    console.log("-------------------------------------------------------------------");
    console.log("");
    console.log("");

    salesOffices.trigger(6000,88);
通用的订阅-发布模式
    //通用的发布模式
    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);
            }
        }
    };

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

    console.log("-----------------------------");
    var salesOffices2={};

    installEvent(salesOffices2);

    salesOffices2.listen("sq88",function(price){
        console.log("我是小明");
        console.log(price);
    });

    salesOffices2.listen("sq99",function(price){
        console.log("我是小红");
        console.log(price);         
    });

    salesOffices2.trigger("sq88",2000);
    salesOffices2.trigger("sq99",3000);
全局的发布-订阅对象
    //全局的发布-订阅 对象

    var hEvent=(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);s
            }else{
                for(var i=0;i<fns.length;i++){
                    var _fn=fns[i];

                    if(_fn===fn){
                        fns.splice(i,1);
                    }
                }
            }
        };

        return {
            listen:listen,
            trigger:trigger,
            remove:remove
        }

    })();

    var xiaoming=function(price){
        console.log("我是小明");
        console.log(price);
    };

    hEvent.listen("sq88",xiaoming);

    hEvent.trigger("sq88",2000);

    setTimeout(function(){
        console.log("再次触发");
        hEvent.trigger("sq88",7000);
    },1000);

    hEvent.remove("sq88",xiaoming);

转载于:https://www.cnblogs.com/hlere/p/6748711.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值