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