js设计模式之等待者模式

原创
2017/07/18 23:54
阅读数 174

等待者模式:通过多个异步进程监听,来触发未来发生的动作。

代码实现:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
	<meta charset="utf-8">
	<style>
		#containers div {
			margin-right: 5px;
			border:solid 1px blue;
			padding: 5px;
			float: left;
		}
	</style>
</head>
<body>
 <div id="container"></div>
 <script type="text/javascript">
 var Waiter = function(){
 	var dfd = [],//注册了的等待对象
 		donArr = [],//成功回调方法容器
 		failArr=[],//失败回调方法容器
 		slice = Array.prototype.slice,//缓存array方法slice
 		that = this;//保存当前等待者对象
 	//监控对象类	
 	var Primise = function(){
 		this.resolved = false;//监控对象是否成功
 		this.rejected = false;//监控对象是否失败
 	}
 	Primise.prototype = {
 		resolve:function(){
 			this.resolved = true;//设置状态为成功
 			if(!dfd.length){
 				return;//如果没有监控对象则终止执行
 			}
 			for(var i=dfd.length-1; i>=0; i--){
 				if(dfd[i] && !dfd[i].resolved || dfd[i].rejected){
 					return;//如果有任意一个监控对象没有成功或失败则返回
 				}
 				dfd.splice(i,1);//清除监控对象
 			}
 			_exec(donArr);//执行成功回调方法
 		},
 		reject : function() {
 			this.rejected = true;//设置状态为失败
 			if (!dfd.length) return;
 			dfd.splice(0);//清除所有监控对象
 			_exec(failArr);
 		}
 	}
 	//创建监控对象
 	that.Deferred = function(){
 		return new Primise();
 	}
 	//回调执行方法
 	function _exec(arr){
 		var i=0,len = arr.length;
 		for(;i<len;i++){
 			try{
 				arr[i] && arr[i]();//执行回调函数
 			}catch(e){}
 		}
 	}
 	that.when = function(){
 		dfd=slice.call(arguments);
 		var i=dfd.length;
 		for(--i;i>=0;i--){//向前遍历监控对象,最后一个监控对象的索引值为length-1
 			//如果不存在监控对象,或者以解决,或者不是监控对象
 			if(!dfd[i] || dfd[i].resolved || dfd[i].rejected || !dfd[i] instanceof Primise){
 				dfd.splice(i,1);//内存清理,清除当前监控对象
 			}
 		}
 		return that;//返回等待者
 	}
 	that.done = function(){
 		doneArr = donArr.concat(slice.call(arguments));//添加回调方法
 		return that;
 	}
 	that.fail = function(){
 		failArr = failArr.concat(slice.call(arguments));
 		return that;
 	}
 }

 //使用方法
 var waiter = new Waiter();
 var first = function(){
 	var dtd = waiter.Deferred();//创建一个监听对象
 	setTimeout(function(){
 		console.log('first finish');
 		//dtd.resolve();//发布成功
 		dtd.reject();
 	},5000);
 	return dtd;
 }();
  var second = function(){
 	var dtd = waiter.Deferred();//创建一个监听对象
 	setTimeout(function(){
 		console.log('second finish');
 		dtd.resolve();
 	},10000);
 	return dtd;
 }();
 waiter.when(first,second)//监听两个事件
 		.done(function(){
 			console.log("success");
 		},function(){
 			console.log("success again")
 		})
 		.fail(function(){
 			console.log('fail');
 		})
 </script>

</body>
</html>

输出结果:

first finish
fail
second finish

 

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部