设计模式(等待者模式)

Posted hsp大鹏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式(等待者模式)相关的知识,希望对你有一定的参考价值。

      最近,闲来会看看《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                 })

   结果

     技术分享

    总结:通过创建不同的监听对象,判断对象状态调用失败或者成功的回调函数

以上是关于设计模式(等待者模式)的主要内容,如果未能解决你的问题,请参考以下文章

多线程的等待唤醒机制之消费者和生产者模式

装饰者模式

生成者消费者模式,如何避免消费者一直处于饥饿状态

设计模式建造者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

设计模式之单例模式

Linux下同步模式异步模式阻塞调用非阻塞调用总结