代理模式

代理英文是proxy,就像经纪人一样,如果有通告需要找到明星,不能直接和明星直接接触,而是要找经纪人,经纪人进行筛选后,然后在和明星进行沟通。经纪人的所作就是代理类的作用

比如小明想送花给小红

下面的代码没有进行任何代理,而是小明直接送给了小红

 1    <script>
 2           function Flower(name) {
 3         this.name = name
 4     }
 5     var xiaoming = (function() {
 6         var flower = new Flower('玫瑰花');
 7         return {
 8             name: '小明',
 9             sendFlower: function(target) {
10                 // 送的目标
11                 target.getFlower(flower, this)
12             }
13         }
14     })()
15     var xiaohong = {
16         getFlower: function(flower, person) {
17             console.log("小红收到了" + person.name + '的' + flower.name)
18     }
19 }
20 xiaoming.sendFlower(xiaohong)
21     </script>

 

 

突然有一天,小红和小明生气了,小明为了哄小红开心,想送小红礼物,但是此时小红由于还在生小明的气,所以不会搭理小明。此时小明想到了小红的闺蜜,让她做代理,然后把礼物送给小红的闺蜜,让闺蜜适时送给小红

 1  <script>
 2          function Flower(name) {
 3             this.name = name
 4         }
 5         var xiaoming = (function() {
 6             var flower = new Flower('玫瑰花');
 7             return {
 8                 name: '小明',
 9                 sendFlower: function(target) {
10                     // 送的目标
11                     target.getFlower(flower, this)
12                 }
13             }
14         })();
15 
16         var guimi = (function() {
17             return {
18                 name: "闺蜜",
19                 flower: null,
20                 sendPerson: null,
21                 // 获取小红心情的状态
22                 getState: function(state) {
23                     // 如果此时小红的心情比较好,送花
24                     if (this.flower && state == "心情很好") {
25                         xiaohong.getFlower(this.flower, this.sendPerson)
26                     }
27                 },
28                 getFlower: function(flower, person) {
29                     // 得到小明的信息和礼物
30                     this.flower = flower.name;
31                     this.sendPerson = person.name;
32                     console.log("闺蜜收到了" + person.name + '的' + flower.name)
33                 }
34             }
35         })();
36 
37         var xiaohong = (function() {
38             var state;
39             var timer = setInterval(function() {
40                 if (Math.random() > 0.5) {
41                     state = '心情很好'
42                 } else {
43                     state = '心情不好'
44                 }
45                 guimi.getState(state)
46             }, 1000)
47             return {
48                 getFlower: function(flower, person) {
49                     // 接收自闺蜜转接的礼物
50                     console.log("小红收到了来自闺蜜转接自" + person + "的" + flower)
51                 }
52             }
53         })()
54         xiaoming.sendFlower(guimi)
55     </script>

 

 

上面的代码中guimi处于一个代理状态,代理的是对小红的事件过程

 

缓存代理

我们可以使用代理模式进行缓存处理,也叫做缓存代理

缓存代理就是记录已经进行的进行(结果),然后再次执行的时候和代理类进行比对,然后判断是抛出已有的,还是执行新的功能

比如我们下面是计算数字的阶乘,已有的计算,我们直接抛出缓存,没有的执行阶乘函数

 

 1   <script>
 2        function factorial(number) {
 3         console.log("对" + number + "的阶乘计算");
 4         for (var i = number, result = 1; i >= 1; i--) {
 5             result *= i;
 6         }
 7         return result;
 8     } 
 9     console.log(factorial(5))
10     </script>

 

 此时我们多输出几个结果会发现

 

 每次都会进行调用函数

 1     <script>
 2       function factorial(number) {
 3     console.log("对" + number + "的阶乘计算");
 4     for (var i = number, result = 1; i >= 1; i--) {
 5         result *= i;
 6     }
 7     return result;
 8 }
 9 // 设置一个代理类,缓存已经计算过的信息
10 var factorialProxy = (function() {
11     var note = {};
12     return function(number) {
13         // 对已有内容的判断
14         return note[number] ? note[number] : note[number] = factorial(number)
15     }
16 })()
17 console.log(factorialProxy(5))
18 console.log(factorialProxy(5))
19 console.log(factorialProxy(5))
20 console.log(factorialProxy(6))
21     </script>

此时我们设置一个代理类会发现,已经进行过的不在输出

 

 

代理类实现图片loading

我们可以通过代理类来实现图片的loading状态显示

 1     <script>
 2    function MyImage(src) {
 3     // 创建节点
 4     this.oImg = document.createElement("img");
 5     // 节点上树
 6     document.body.appendChild(this.oImg);
 7 }
 8 MyImage.prototype.setSrc = function(src) {
 9     this.oImg.src = src;
10 };
11 // 代理类
12 function MyImageProxy(src) {
13     this.myImage = new MyImage();
14     // 给图片设置初始的loading状态,防止如果图片不能预期加载,或者图片加载缓慢的时候的替换状态
15     this.myImage.setSrc("images/loading.gif");
16     // image就是一个 钩子,作用是用来表示当图片加载完毕之后,让MyIamge的实例进行渲染
17     var image = new Image();
18     image.src = src;
19     var self = this;
20     // onload表示当图片加载完毕之后,此时的图片是整张图的状态,而不是部分渲染
21     image.onload = function() {
22         self.myImage.setSrc(src)
23     }
24 }
25 new MyImageProxy("images/0.jpg")
26 new MyImageProxy("images/1.jpg")
27 new MyImageProxy("images/2.jpg")
28     </script>

此时我们降低网速可以看到loading效果

posted @ 2021-09-26 17:48  keyeking  阅读(39)  评论(0编辑  收藏  举报