javascript设计模式中的订阅者模式怎么实现

发布时间:2022-01-12 18:08:04 作者:iii
来源:亿速云 阅读:128

本篇内容介绍了“javascript设计模式中的订阅者模式怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一. 初识代理模式

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。它的用处就是当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问。通俗来讲就是,代理是一个中间人,负责在客户和卖家之间传递信息,将没用的信息过滤,将有利于交易成功的信息传递给卖家,从而加大交易的成功率。

二. 代理模式的实现思想

现在我们来通过一个小明给女神送花的例子来实现代理模式。

没有使用代理模式

        let Flower = function () {};
        let xiaomingFirst = {
            sendFlower ( target ) {
                let flower = new Flower();
                target.receiveFlower( flower );
            }
        }
        let A = {
            receiveFlower ( flower ) {
                console.log('收到花')
            }
        }
        xiaomingFirst.sendFlower(A);

使用代理模式重构

设定一个需求AA 为小明的女神,AA 在心情好的时候接受小明花的几率更大,而 B 是 AA 和小明的好朋友,因此小明将花送给 B,让 B 在 AA 心情好时转告自己的心意。

分析:重构后的代码增加了一个新的对象 B , 此时 为 AA 的代理,监听 AA 的好心情,代码中假定5秒后 AA 心情变好,将花送出。

        let xiaomingSencend = {
            sendFlower ( target ) {
                let flower = new Flower();
                target.receiveFlower( flower );
            }
        }
        let AA = {
            receiveFlower () {
                console.log('收到花');
            },
            listenGoodMood ( fn ) {
                setTimeout(()=>{
                    fn();
                }, 5000);
            }
        }
        let B = {
            receiveFlower ( flower ) {
                AA.listenGoodMood( ()=>{
                    AA.receiveFlower( flower );
                } );
            }
        }
        xiaomingSencend.sendFlower(B);

三. 代理模式分类

上述代码中代理模式可能显得不那么重要,但是体现了代理的思想,假如女神有一些要求,给他送花的男生必须帅而有钱,但又不能显得那么势力,因此代理可以帮其过滤掉这些不符合要求的男生,减少自己的许多麻烦,还能保持自己的美好形象这就是代理的用处。再者说,买一朵花很昂贵,而不是单单 new 这么简单,男生不想浪费自己的钱,因此想先确定女神是否接受自己的花,便让代理帮忙询问,如果女神接受则让代理帮忙买一朵送给女神,这样减少了男生的损失但也达成了目的,这便引出了以下两种代理模式。

四. 虚拟代理模式的实际运用

1. 虚拟代理实现图片预加载

分析:先加载本地图片,然后开始发起请求获取图片,当图片加载获取成功后,再调用 myImage 将图片替换预加载时显示的图片。

    let myImage = function () {
        let img = document.createElement('img');
        document.body.appendChild(img);
        return {
            setSrc ( src ) {
                img.src = src;
            }
        }
    }();
    proxyImage = function () {
        let img = new Image;
        img.onload = function () {
            myImage.setSrc( this.src );
        }
        return {
            setProxyImage( src ) {
                myImage.setSrc("https://cache.yisu.com/upload/information/20220112/112/58.jpg@1280w_1l_2o_100sh.jpg"); // 此处为加载 loading 图片,用来占位,本地图片(作者使用网络图片)
                img.src = src;
            }
        }
    }();
    proxyImage.setProxyImage("https://cache.yisu.com/upload/information/20220112/112/59.jpg@1280w_1l_2o_100sh.jpg");

 2. 缓存代理

分析:在代理中将本体计算的结果进行缓存,如果下次再遇到同样的请求,直接从缓存中获取,减少对本体的访问,减少性能消耗。

        // 计算乘积的函数
        let mult = function (...arg) {
            console.log('我执行了')
            let m = 1;
            for(let i = 0,l = arg.length; i <l; i++){
                m *= arg[i];
            }
            return m;
        }
        // 缓存代理
        let proxyMult = function( fn ) {
            let cache = {};
            return function (...arg) {
                let argS = arg.join(',');
                if( cache[argS] ) {
                    return cache[argS];
                }
                return cache[argS] = fn.apply( this, arg);
            }
        };
        let proxymult = proxyMult(mult);
        console.log(proxymult(1,2,4))

3. 虚拟代理合并 Http 请求

使用场景:点击复选框向服务器发起请求同步文件,每次点击复选框便发起一次请求,造成巨大网络开销,此时我们优化的方式为,将想同步的文件缓存下来,在 3 秒后通过一次请求发送到服务器。

    <input type="checkbox" >1
    <input type="checkbox" >2
    <input type="checkbox" >3
    <input type="checkbox" >4
    <input type="checkbox" >5
    <input type="checkbox" >6
    <input type="checkbox" >7
    <input type="checkbox" >8
    <script>
        // 同步文件
        let synchronousFile = function ( id ) {
            console.log("开始同步文件" + id);
        }
        // 代理实现同步文件
        let proxySynchronousFile = function ( ) {
            let cache = [];
            let time;
            return function ( id ) {
                cache.push( id );
                if( time ) {
                    return;
                }
                time = setInterval(() => {
                    synchronousFile(cache.join(','));
                    clearInterval(time);
                    time = null;
                    cache.length = 0;
                }, 3000);
            }
        }()
        // 添加点击执行
        let checkboxList = document.getElementsByTagName('input');
        for(let i = 0, l = checkboxList.length; i < l; i++) {
            checkboxList[i].onclick = function() {
                if( this.checked === true ) { 
                    proxySynchronousFile(i+1);
                }
            }
        }

五. 代理的使用意义及要求

意义:首先我们引入面向对象设计原则,单一职责原则,一个对象应该尽可能少的承担职责,最好是一个,如果承担职责过多,会提高代码的耦合度,从而导致脆弱和低内聚的设计。当变化发生,设计可能遭到意外破坏,即使实现同样需求可以将代码封装到一个函数中,但是最好的处理措施是引入代理模式

要求:代理和本体接口要一致,在任何使用本体地方都可以用代理来代替

“javascript设计模式中的订阅者模式怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

推荐阅读:
  1. JavaScript中观察者模式与发布订阅模式的用法
  2. 原生js如何实现观察者和订阅者模式

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

javascript

上一篇:在小程序中如何实现3d裸眼轮播效果

下一篇:Vue的数据及事件绑定和filter过滤器的方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》