设计模式(等待者模式)
最近,闲来会看看《javascript设计模式》这本书,空闲时间我会把看到的写出来,和大家一起分享今天先来一个等待者模式。
等待者模式:通过对异步进程监听,来触发未来发生的动作
举例子:异步进程A,B,需要两个进程都完成以后才能进行C进程操作,这时可以使用等待者模式。
平时在开发中经常会这样,需要等到上个程序完成或者知道上个程序完成才去触发下个程序,这时就可以等待者模式。说的不是很清楚咱们看代码:
代码详情
1 var Waiter = function() { 2 var dfd = [], //等待对象容器 3 doneArr = [], //成功回调容器 4 failArr = [], //失败回调容器 5 slice = Array.prototype.slice, 6 that = this; 7 //监控对象类 8 var Promise = function() { 9 //监控对象是否解决成功状态 10 this.resolved = false; 11 //监控对象是否解决失败状态 12 this.rejected = false; 13 } 14 Promise.prototype = { 15 //解决成功 16 resolve: function() { 17 //设置当前监控状态是成功 18 this.resolved = true; 19 if(!dfd.length) return; 20 console.log("进来"); 21 //对象监控对象遍历如果任一个对象没有解决或者失败就返回 22 for(var i = dfd.length - 1; i >= 0; i--) { 23 if(dfd[i] && !dfd[i].resolved || dfd[i].rejected) { 24 return; 25 } 26 dfd.splice(i, 1); 27 } 28 _exec(doneArr) 29 }, 30 //解决失败 31 reject: function() { 32 //设置当前监控状态是失败 33 this.rejected = true; 34 //没有监控对象取消 35 if(!dfd.length) return; 36 //清楚监控对象 37 dfd.splice(0) 38 _exec(failArr) 39 } 40 } 41 that.Deferred = function() { 42 return new Promise(); 43 }; 44 //回调执行方法 45 function _exec(arr) { 46 var i = 0, 47 len = arr.length; 48 for(; i < len; i++) { 49 try { 50 arr[i] && arr[i](); 51 } catch(e) {} 52 } 53 }; 54 //监控异步方法参数:监控对象 55 that.when = function() { 56 //设置监控对象 57 console.dir(arguments) 58 dfd = slice.call(arguments); 59 var i = dfd.length; 60 //向前遍历监控对象,最后一个监控对象索引值length-1 61 for(--i; i >= 0; i--) { 62 //不存在监控对象,监控对象已经解决,监控对象失败 63 if(!dfd[i] || dfd[i].resolved || dfd[i].rejected || !dfd[i] instanceof Promise) { 64 dfd.splice(i, 1) 65 } 66 } 67 //返回等待者对象 68 return that; 69 }; 70 //解决成功回调函数添加方法 71 that.done = function() { 72 //向成功毁掉函数容器中添加回调方法 73 doneArr = doneArr.concat(slice.call(arguments)); 74 return that; 75 }; 76 //解决失败回调函数添加方法 77 that.fail = function() { 78 //向失败回调函数中添加方法 79 failArr = failArr.concat(slice.call(arguments)); 80 return that; 81 }; 82 }
测试:
1 var waiter = new Waiter();//创建一个等待者实例 2 var first = function() { 3 var dtd = waiter.Deferred(); 4 setTimeout(function() { 5 dtd.resolve(); 6 }, 5000) 7 return dtd;//返回监听这对象 8 }() 9 var second = function() {//第二个对象 10 var dtd = waiter.Deferred(); 11 setTimeout(function() { 12 dtd.resolve(); 13 }, 10000) 14 return dtd; 15 }() 16 waiter.when(first, second).done(function() { 17 console.log("success") 18 }, function() { 19 console.log("success again") 20 }).fail(function() { 21 console.log("fail") 22 })
结果
总结:通过创建不同的监听对象,判断对象状态调用失败或者成功的回调函数