懒人封装(懒惰模式)

  • 本文旨在一些特殊的封装上
  • 一般会用于处理浏览器兼容性的封装
  • 但是看完会对你有一些启发也说不定哦 O(∩_∩)O~

一段简单的代码

  • 我们在封装 ajax 请求的时候
  • 基于原生 js 的 ajax 代码, 如果考虑到浏览器兼容问题
  • 那么我们一定会看到以下几段代码
// 标准浏览器下创建 ajax 对象
new XMLHttpRequest();
// 以下三种都是IE浏览器,对应不同版本
new ActiveXObject('Msxml12.XMLHTTP');
new ActiveXObject('Msxml13.XMLHTTP');
new ActiveXObject('Microsoft.XMLHTTP');

开始第一次封装

想到就做, 我们就来进行一次封装试试看

function xhl_ajax(options) {
    // ...
    let xml = null
    if (window.XMLHttpRequest) {
        xml = new XMLHttpRequest()
    } else if (new ActiveXObject) {
        xml = new new ActiveXObject('Microsoft.XMLHTTP')
    } else {
        xhl = '你的浏览器可能不支持 ajax 请求, 请更换浏览器再试'
    }
    // ...
}

我这里并没有写完整, 只是简单一个小示例

我们来分析一下这个事情

    • 我们的判断种类可能有很多种, 比如 A B C D 四种
// 那么这一段代码就变成了
function xhl_ajax() {
    // ...
    if (A) {
        // ...
    } else if (B) {
        // ...
    } else if (C) {
        // ...
    } else if (D) {
        // ...
    } else {
        // ...
    }
    // ...
}
  • 代码可能就变成了这个样子
  • 可能有的小伙伴会想到, 我改成 策略模式 封装不就好了

我要说的不是这个问题

    • 不管你改成什么模式封装, 哪怕是起飞模式
    • 如果你当前需要匹配到的内容是 D
    • 那么每调用一次, 都会从 A 开始判断一次
    • 然后到达 D
// 第一次调用
xhl_ajax() // 需要判断 A 不对, B 不对, C 不对, D 对了

// 第二次调用
xhl_ajax() // 需要判断 A 不对, B 不对, C 不对, D 对了

// ...
  • 想象一下, 如果调用了 100 次, 那么每次的前三个判断是不是都浪费了呢
  • 好像是这样的
    • 那我们是不是可以考虑换一个方式来搞一下

懒惰模式封装这段代码

  • 我们能不能考虑一下, 我封装完毕的代码, 只有第一次调用的时候会判断
  • 后面调用的时候不在判断了, 那么是不是会节省很多呢 ?
  • 想到就做
    • 原则就是多个事情依次完成
    • 前一个成功了, 后面的不做了
    • 只要成功过一次, 以后就不在尝试了

  1. 把我们需要做的几个事情放在几个函数内
function createXHR1 () {
  return new XMLHttpRequest;
}
function createXHR2 () {
  return new XActiveXObject("Microsoft.XMLHTTP");
}
function createXHR3 () {
  return new ActiveXObject("Msxml2.XMLHTTP");
}
function createXHR4 () {
  return new ActiveXObject("Msxml3.XMLHTTP");
}
  • 这样一来, 如果第一个能成功, 那么我们调用第一个函数就回得到对应的 ajax 对象了
  • 如果第一个不行, 我们就尝试第二个

2. 接下来我们把四个函数放在一个数组内, 遍历依次执行

  • 只要找到一个合适的就行了
var xmls = [createXHR1, createXHR2, createXHR3, createXHR4]
let xml = null
for (var i = 0; i < xmls.length; i++) {
    // 一旦 xml 有内容了, 不再是 null 了, 那么直接结束循环
    if (xml) break
    // 否则就开始尝试
    xml = xmls[i]()
}
  • 问题随之而来了, 如果第一个不对, 那么会报错
  • 我的代码就全部挂掉了

  1. 尝试使用 try catch 解决问题
  • 为了不让我的代码挂掉
  • 我们改用 try catch 来解决问题
var xmls = [createXHR1, createXHR2, createXHR3, createXHR4]
let xml = null
for (let i = 0; i < xmls.length; i++) {
    try {
        xml = xmls[i]()
    } catch(e) {}
}
  • 错了也不需要做什么 , 直接下一次就好了
  • 看上去挺好, 但是问题依旧没有解决

  1. 单独制作一个函数
  • 我的原则就是, 让这个函数第一次调用和第二次调用不是一个函数就好了
  • 也就是我要在第一次调用完毕以后修改这个函数
function createXHR() {
  // 定义一个 xhr 接收 ajax 对象
  // 定义一个 flag 开关,看看是否找到合适的创建 ajax 对象的方法
  // 定义一个数组,存储四种创建 ajax 对象的方式
  let xml = null,
    flag = false,
    xmls = [
      function () {
        return new XMLHttpRequest;
      },
      function () {
        return new ActiveXObject("Microsoft.XMLHTTP");
      },
      function () {
        return new ActiveXObject("Msxml2.XMLHTTP");
      },
      function () {
        return new ActiveXObject("Msxml3.XMLHTTP");
      }
    ];
  // 依旧是循环遍历数组
  for (let i = 0, len = xmls.length; i < len; i++) {
    let curFn = ary[i];
    // 依次执行,找到合适的创建 ajax 对象的方法
    try {
      xml = curFn();
      // 这里是核心,一旦找到合适的方法,那么我们就把这个函数重新赋值给 createXHR
      createXHR = curFn;
      // 让开关为 true
      flag = true;
      break;
    } catch (e) {
    }
  }
  // 如果到最后开关依旧为 false,证明四种方法都不合适,那么我们就需要提醒浏览器升级
  if (!flag) {
    throw new Error("your browser is not support ajax, please change your browser,try again!");
  }
  // 最后返回 ajax 对象
  return xml;
}
  • 看似没有什么改变,但是之一第 28 行的代码,有一个重写 createXHR
  • 这个是整个”惰性思想”的核心,也就是说,我只有在当前浏览器中,第一次执行 createXHR 的时候是这个函数
  • 一旦找到一个合适的创建 ajax 对象的方法以后,那么从第二次执行 createXHR 开始,就全部都是我们之前数组中的某一个函数了
  • 再也不用循环判断,而是直接用一种有效的方法创建一个 ajax 对象了
  • 这个是一种 js 中的高级编程思想,如果理解不了,就用我们最开始写的判断的形式来进行就可以,慢慢体会一段时间就能明白了

完整代码

function createXHR() {
  let xml = null,
    flag = false,
    xmls = [
      function () {
        return new XMLHttpRequest;
      },
      function () {
        return new ActiveXObject("Microsoft.XMLHTTP");
      },
      function () {
        return new ActiveXObject("Msxml2.XMLHTTP");
      },
      function () {
        return new ActiveXObject("Msxml3.XMLHTTP");
      }
    ];
  for (let i = 0, len = xmls.length; i < len; i++) {
    let curFn = ary[i];
    try {
      xml = curFn();
      createXHR = curFn;
      flag = true;
      break;
    } catch (e) {
    }
  }
  if (!flag) {
    throw new Error("your browser is not support ajax, please change your browser,try again!");
  }
  return xml;
}

function xhl_ajax(options) {
    // ...
    const xml = createXHR()
    // ...
}
  • 从此以后, 你就去随便调用吧
  • 只有第一次的时候会进行判断, 后面的时候都不会进行判断了
  • 直接就能使用个最准确的了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/4280.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Typora使用

Typora Typora 是一款支持实时预览的 Markdown 文本编辑器。 1. 基础操作 1.1标题 # 一级标题## 二级标题### 三级标题#### 四级标题##### 五级标题###### 六级标题1.2 引用 > 引用内容1 > 引用内容2 >> 引用内容31.3 斜体 *斜体* _斜体_1.4 加粗…

mysql整理

文章目录概述SQLDDLDMLDQL单表查询多表查询DQL的执行顺序DCL管理用户控制权限函数约束事务存储引擎索引概述语法性能分析索引的使用SQL的优化insert优化主键优化Order by优化其它优化存储对象视图存储过程基本操作变量IF条件判断参数循环条件处理程序存储函数触发器锁全局锁表级…

Mysql-缓冲池 buffer pool

缓冲池 buffer pool innodb中的数据是以【页】的形式存储在磁盘上的表空间内&#xff0c;但是【磁盘的速度】和【内存】相比简直不值一提&#xff0c;而【内存的速度】和【cpu的速度】同样不可同日而语&#xff0c;对于数据库而言&#xff0c;I/O成本永远是不可忽略的一项成本…

基于Elman神经网络预测计费系统的输出(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 简单循环网络&#xff08;simple recurrent networks&#xff0c;简称SRN&#xff09;又称为Elman network&#xff0c;是由Jeff…

什么是AI文章生成器-AI文章生成器批量生成文章

AI文章生成器有哪些 目前市面上存在一些可以生成文章的 AI 文章生成器&#xff0c;以下是其中几种常见的&#xff1a; OpenAI GPT-3&#xff1a; OpenAI GPT-3 是目前最先进、最著名的 AI 文章生成器之一&#xff0c;它可以生成各种类型的文章&#xff0c;例如新闻报道、科学报…

我的Macbook pro使用体验

刚拿到Mac那一刻&#xff0c;第一眼很惊艳&#xff0c;不经眼前一亮&#xff0c;心想&#xff1a;这是一件艺术品&#xff0c;太好看了吧 而后再体验全新的Macos 系统&#xff0c;身为多年的win用户说实话一时间还是难以接受 1.从未见过的访达&#xff0c;不习惯的右键 2. …

[论文解析] Cones: Concept Neurons in Diffusion Models for Customized Generation

论文连接&#xff1a;https://readpaper.com/pdf-annotate/note?pdfId4731757617890738177&noteId1715361536274443520 源码链接&#xff1a; https://github.com/Johanan528/Cones 文章目录OverviewWhat problem is addressed in the paper?Is it a new problem? If so…

PMP一般要提前多久备考?

PMP很迷&#xff0c;有只备考了一周过的&#xff0c;也有备考几个月过的。保险起见&#xff0c;预留两个月比较靠谱&#xff0c;尤其现在是新考纲&#xff0c;PMP新版大纲加入了 ACP 敏捷管理的内容&#xff0c;而且还不少&#xff0c;敏捷混合题型占到了 50%&#xff0c;前不久…

AcWing3662. 最大上升子序列和(线性DP + 树状数组优化 + 离散化处理)

AcWing3662. 最大上升子序列和&#xff08;线性DP 树状数组优化 离散化处理&#xff09;一、问题二、分析1、DP过程&#xff08;1&#xff09;状态表示&#xff08;2&#xff09;状态转移2、数据结构优化&#xff08;1&#xff09;树状数组维护最值&#xff08;2&#xff09;…

K8s 弃用 Docker!一文介绍 containerd ctr、crictl 使用

containerd 是一个高级容器运行时&#xff0c;又名 容器管理器。简单来说&#xff0c;它是一个守护进程&#xff0c;在单个主机上管理完整的容器生命周期&#xff1a;创建、启动、停止容器、拉取和存储镜像、配置挂载、网络等。 containerd 旨在轻松嵌入到更大的系统中。Docke…

【ASPLOS 2023】图神经网络统一图算子抽象uGrapher,大幅提高计算性能

作者&#xff1a;周杨杰、沈雯婷 开篇 近日&#xff0c;阿里云机器学习平台PAI和上海交通大学冷静文老师团队合作的论文《图神经网络统一图算子抽象uGrapher》被ASPLOS 2023录取。 为了解决当前图神经网络中框架中不同的图算子在不同图数据上静态kernel的性能问题&#xff0…

【前沿技术】文心一言 PK Chat Gpt

目录 写在前面 一、文心一言 二、Chat GPT 三、对比 四、总结 写在前面 随着人工智能技术的不断发展和普及&#xff0c;越来越多的智能应用走入了人们的日常生活&#xff0c;如智能语音助手、智能客服、机器翻译等等。在这些应用中&#xff0c;自然语言生成&#xff08;…

看完不再愁 | 图解TCP 重传、滑动窗口、流量控制、拥塞控制

目录 前言 正文 &#x1f332; 重传机制 1. 超时重传 2. 快速重传 3. SACK 方法 4. Duplicate SACK &#x1f332; 滑动窗口 &#x1f333; 流量控制 &#x1f333; 拥塞控制 1. 慢启动 2. 拥塞避免算法 3. 拥塞发生 4. 快速恢复 前言 前面我们讲到「硬不硬你说…

Android开发一直在用大公司的开源库,可参考~

一、阿里巴巴 &#xff08;一&#xff09;UI有关 1. 多页面切换场景统一解决方案 UltraViewPager UltraViewPager 是阿里开源的一个封装多种特性的 ViewPager &#xff0c;主要是为多页面切换场景提供统一解决方案。 主要功能: 1. 支持横向滑动&#xff0f;纵向滑动2. 支持一屏…

求红白黑球的个数-课后程序(JavaScript前端开发案例教程-黑马程序员编著-第2章-课后作业)

【案例2-11】求红白黑球的个数 一、案例描述 考核知识点 for循环语句、if判断语句 练习目标 掌握for循环应用。掌握if判断语句应用 需求分析 用js编程 已知&#xff1a;红白球共25个&#xff0c;白黑球共31个&#xff0c;红黑球共28个&#xff0c;求三种球各有多少&#xff…

基于STM32 SG90 9g舵机控制

文章目录一、什么是舵机&#xff1f;二、工作原理三、利用PWM控制四、stm32舵机控制一、什么是舵机&#xff1f; 产品参数 名称&#xff1a;9克舵机180度 尺寸&#xff1a;23mm X 12.2mm X 29mm 重量&#xff1a;9克 扭矩&#xff1a;1.5kg/cm 工作电压&#xff1a;4.2 - 6V 温…

Java大数字运算(BigInteger类和BigDecimal类)

在 Java 中提供了用于大数字运算的类&#xff0c;即 java.math.BigInteger 类和 java.math.BigDecimal 类。这两个类用于高精度计算&#xff0c;其中 BigInteger 类是针对整型大数字的处理类&#xff0c;而 BigDecimal 类是针对大小数的处理类。 BigInteger 类 如果要存储比 …

一本通 3.3.1 树与二叉树

树与二叉树的基本知识 1336&#xff1a;【例3-1】找树根和孩子 【题目描述】 给定一棵树&#xff0c;输出树的根root&#xff0c;孩子最多的结点max以及他的孩子。 【题目分析】 【代码实现】 #include<bits/stdc.h> using namespace std; int father[201], sum[101]…

8.OSP的GR(Graceful Restart,平滑重启)实验

一、GR(Graceful Restart,平滑重启) 技术介绍 GR(Graceful Restart,平滑重启)技术保证了设备在重启过程中转发层面能够继续指导数据的转发,同时控制层面邻居关系的重建以及路由计算等动作不会影响转发层面的功能,从而避免了路由振荡引发的业务中断,保证了关键业务的数…

Java_Spring:5. 基于注解的 IOC 配置

目录 1 环境搭建 1.1 第一步&#xff1a;拷贝必备 jar 包到工程的 lib 目录。 1.2 第二步&#xff1a;使用Component 注解配置管理的资源 1.3 第三步&#xff1a;创建 spring 的 xml 配置文件并开启对注解的支持 2 常用注解 2.1 用于创建对象的注解 2.1.1 Component 2.1…
最新文章