JavaScipt设计模式初探-代理模式(三) 虚拟代理
文章目录
- 前言
- 一、举例_图片懒加载
- 二、虚拟代理在示例中的体现
- 总结
前言
虚拟代理是代理模式在性能方面的分支, 个人认为有点像人工异步操作.
把累活和细活从真实对象拆出来丢给代理对象, “你做完之后叫我一声, 我来拿结果.”
那么可以把开销大的操作, 或者网络请求放到代理对象执行, 等到做完的时候调用真实对象的方法回来拿, 在这个空当里真实对象可以先去应付一些其他的事情.
另外有时候为了符合代码职责单一原则, 也会用虚拟代理把请求和业务逻辑分离.
一、举例_图片懒加载
我在初探代理模式, 也就是这个系列的首篇里举过这个例子, 当时我还不知道…它不仅仅是代理模式而且还是虚拟代理.
不过这次会从虚拟代理角度看这个案例, 而不仅仅是"代理模式"的角度.
完整代码:
window.onload = function () {var myImage = (function () {var imgNode = document.createElement("img");document.body.appendChild(imgNode);return {setSrc: function (src) {imgNode.src = src;}})()var proxyImage = (function () {var img = new Image(); //内存中的一个图片对象img.onload = function () { //加载完毕触发方法setTimeout(() => {myImage.setSrc(this.src);//this == img }, 2000)}return {setSrc: function (src) {myImage.setSrc("http://img.lanrentuku.com/img/allimg/1212/5-121204193R0.gif");img.src = src //真实图片}}})()proxyImage.setSrc("https://www.baidu.com/img/bd_logo1.png")}
然后先看一下代码思路:
自proxyImage
之后, 调用proxyImage
的setSrc
, 看向proxyImage
的setSrc
, 此时会调用myImage
的setSrc
导致imgNode
的src
成为加载gif.
而同时myImage.setSrc(this.src)
设置的this.src
即img.src
此时拥有了真正的图片地址(要加载的图片地址), 但是还不会呈现.
var proxyImage = (function () {var img = new Image();return {setSrc: function (src) {myImage.setSrc("http://img.lanrentuku.com/img/allimg/1212/5-121204193R0.gif");img.src = src;}}
})()
这种情况直到proxyImage
的计时器完成才有所改变, myImage.setSrc
被再次调用, 传入了要加载的图片地址: img.onload的this.src
, 即img.src
,
var proxyImage = (function () {img.onload = function () { //加载完毕触发方法setTimeout(() => {myImage.setSrc(this.src); //this == img }, 2000)}
})()
此时imgNode.src
被赋值为img.src
即要加载的图片地址:
var myImage = (function () {var imgNode = document.createElement("img");//document.body.appendChild(imgNode);return {setSrc: function (src) {imgNode.src = src;}}
})()
这样看来img对象在这个过程中担任一个存储的作用, 请求要用的图片并且直至其加载好.
所以2s后imgNode.src
改变, 呈现要加载的图片.
二、虚拟代理在示例中的体现
加载真实图片这个事情交给代理去做, 我真实对象先去展示加载中图片了, 等到你代理对象那边加载完了图片叫我一声(调用我)我回来拿.
先实例化一个img对象用于对真实图片进行加载和存储, 并且用onload
事件监听:
var proxyImage = (function () {var img = new Image(); //内存中的一个图片对象return {setSrc: function (src) {//...img.src = src //真实图片}}})()
proxyImage.setSrc("https://www.baidu.com/img/bd_logo1.png")
与此同时真实对象的setSrc
受到调用, 设置了加载中图片:
var proxyImage = (function () {return {setSrc: function (src) { //未使用参数scr的语句设置了默认图片myImage.setSrc("http://img.lanrentuku.com/img/allimg/1212/5-121204193R0.gif");}}})()proxyImage.setSrc("https://www.baidu.com/img/bd_logo1.png")
剩下的就是监听真实图片的加载, 这里为了效果明显, 让图片加载完后再延迟2s呈现:
var proxyImage = (function () {var img = new Image(); //内存中的一个图片对象img.onload = function () { //加载完毕触发方法setTimeout(() => {myImage.setSrc(this.src); //this == img }, 2000)}return {setSrc: function (src) {img.src = src //真实图片}}
})()proxyImage.setSrc("https://www.baidu.com/img/bd_logo1.png")
最后, 遵循代理模式最基本特点: 代理对象与真实对象应当具有相同行为.
所以代理对象代替真实对象设置图片时, 也必须与"真实对象亲自设置图片"时使用的方法相同, 所以选择了直接调用myImage
的setSrc
.
总结
上一篇: JavaScipt设计模式初探-代理模式(二) 保护代理
JavaScipt设计模式初探-代理模式(三) 虚拟代理相关推荐
- 设计模式——代理模式(虚拟代理)
代理模式的类型分为: (1)虚拟代理 (2)远程代理 (3)智能指引 (4)保护代理 这一篇主要讲虚拟代理,想要知道其他类型讲解的小伙伴可以去我其他博客翻一翻哦. 首先来理解一波虚拟代理,啥叫虚拟代理 ...
- 【设计模式】学习笔记16:代理模式之虚拟代理(实现CD封面加载器)
本文出自 http://blog.csdn.net/shuangde800 在上篇中,我们学习了代理模式,并用Java RMI实现了一个最简单的远程代理. 实际上代理模式并不仅仅应用与远程代理,还 ...
- 代理模式之虚拟代理(仅了解)
[0]README 0.1)本文全文转自 "head first 设计模式",旨在了解 虚拟代理+动态代理: 0.2)晚辈我 java.swing 烂到渣,没有写出干货荔枝,抱歉: ...
- 【学习笔记】结合代码理解设计模式 —— 代理模式(静态代理、动态代理、延伸)
文章目录 什么是代理模式 一. 代理模式简介 二. 静态代理模式 三. 动态代理模式 万能模版 前言:笔记基于狂神设计模式视频.<大话设计模式>观后而写 (最近一直在更新之前的刷题博客,今 ...
- 【设计模式】--- 装饰器模式、静态代理模式和动态代理模式
文章目录 1 引子 2 业务场景介绍 3 静态代理模式 4 装饰器模式 5 动态代理模式 5.1 Proxy --- 具体的代理对象生成组件 5.2 InvocationHandler --- 封装被 ...
- 23种设计模式7_代理模式之一静态代理
23种设计模式7_代理模式之一静态代理 1 基本介绍 代理模式:为其他对象提供一种代理以控制对这个对象的访问 代理模式也叫委托模式,它是一项基本设计技巧.许多其他的模式,如状态模式.策略模式.访问者模 ...
- 设计模式之代理模式(静态代理、Java动态代理、Cglib动态代理)
代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问.这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介. 提醒:动态代理中涉及到以前的一些知识 ...
- 设计模式—代理模式以及动态代理的实现
代理模式(Proxy Design Pattern)是为一个对象提供一个替身,以控制对这个对象的访问.即通过代理对象访问目标对象.被代理的对象可以是远程对象.创建开销大的对象或需要安全控制的对象. 一 ...
- 设计模式之代理模式(静态代理动态代理)
目录 1.什么是代理模式 2.代理模式的结构 3.代理模式的实现 3.1 静态代理和动态代理概念 3.2 静态代理 3.3 动态搭理 3.3.1 代码实现 3.3.2 Proxy类讲解 4.动态代理V ...
最新文章
- 5G会用什么样的语音通信方案?
- HUE配置文件hue.ini 的database模块详解(包含qlite、mysql、 psql、和oracle)(图文详解)(分HA集群和非HA集群)...
- 飞鸽传书绿色版 部分数据库被陆续公开了
- 微博多尺度序列推荐算法实践
- Linux下安装anaconda,创建虚拟环境python3.7,并且安装深度学习框架pytorch进行模型训练
- html图片过渡,CSS3 过渡
- 谢惠民,恽自求,易法槐,钱定边编数学分析习题课讲义16.2.3练习题参考解答[来自陶哲轩小弟]...
- 艾司博讯:拼多多商品讲解视频如何制作
- R语言开发之我想要使用R语言进行开发的原因
- 达梦8,关于参数CTAB_SEL_WITH_CONS的验证
- Navicat还原nb3备份文件步骤
- 类的访问权限-public、private、protected
- 分享|破世界纪录的OceanBase,如今入选了国际顶会VLDB 2022
- java计算机毕业设计新能源汽车租赁管理系统源码+数据库+系统+lw文档+mybatis+运行部署
- 【狂神说Java】---JavaWeb
- 付利赚团队分享互联网发展过程那些疯狂的时代
- [论文笔记] In-Memory Fuzzing for Binary Code Similarity Analysis
- 用于多核DSP开发的核间通信
- 穿越派·派盘 + 静读天下 = 顶级电子书阅读器
- Ubuntu16.04调试北阳(HOKUYO)UST-20LX激光雷达