函数节流
一种限制函数被频繁调用的解决方案,比如我们在 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);