1. 背景

在一些项目中,有时候会出现不同模块重复请求大量相同api接口的情况,特别是在一些功能相似的后台管理页面中。以下面这几个页面为例,每次进入页面都需要请求等大量重复的下拉框数据,下拉框数据短时间内改动不大,但也不能在前端使用静态数据,所以可以考虑在前端进行数据缓存,避免重复请求api。

2. 实现思路

主要有以下3个步骤:

  • 初次获取数据,从服务器中请求数据;
  • 建立一个映射表,将下拉框数据保存起来,并同时记录该数据的时间戳;
  • 后续再次请求时,首先从映射表中查找数据,如果可以查到数据且数据没过期,则直接使用数据,否则重新从服务器中获取数据;

3. 具体实现

3.1 初次获取数据

以下代码中,首先调用 getLocalData 方法查找缓存,如果没找到缓存,就向服务器请求数据(this.$api.task.getCateListAll),获取到数据后用 setLocalData 方法把数据缓存起来。

// 任务类型下拉框数据
// 首先判断是否有缓存
if (!this.getLocalData('cate')) {
/** 初次请求数据 */
await this.$api.task.getCateListAll().then((res) => {
this.m_taskPropOption.cate = this.$u.array.arrToSelect(res.data); // 使用数据
this.m_taskPropDict.cate = this.$u.array.arrToObj(this.m_taskPropOption.cate, "id"); // 使用数据
this.setLocalData('cate'); // 缓存数据
});
}

3.2 建立映射表,缓存数据

缓存数据主要使用了浏览器的API localStorage,如下面代码中 setLocalData 方法,每次从服务器获取数据后,根据 key 将数据保存在 localStorage 中,并且同时记录时间戳,记录时间戳是为了后面检查缓存数据的过期时间:

/** 设置缓存 - 建立映射表 */
setLocalData(key) {
// 缓存数据
localStorage.setItem(`task_${key}_option`, JSON.stringify(this.m_taskPropOption[key])); // 缓存数据
localStorage.setItem(`task_${key}_dict`, JSON.stringify(this.m_taskPropDict[key])); // 缓存数据
localStorage.setItem(`task_${key}_timestamp`, Date.now()); // 记录时间戳
}

3.3 查找缓存数据

根据方法 getLocalData ,首先根据 keylocalStorage 中查找缓存的时间戳(时间戳是在缓存数据时一起保存的,如果有时间戳,则表示有缓存数据),如果有缓存时间并且判断缓存时间未过期,则进一步从缓存中获取数据给到程序使用:

/** 获取缓存 - 查找映射表 并 检查过期时间 */
getLocalData(key) {
let storageTimestamp = localStorage.getItem(`task_${key}_timestamp`);
let expires = 1000 * 3600; // 有效时间
let timestamp = Date.now(); // 当前时间戳
// 从缓存中取数据(1h内数据)
if (storageTimestamp && (timestamp - storageTimestamp) < expires) {
let option = localStorage.getItem(`task_${key}_option`); // 从缓存中拿到数据给程序使用
let dict = localStorage.getItem(`task_${key}_dict`); // 从缓存中拿到数据给程序使用
this.m_taskPropOption[key] = JSON.parse(option);
this.m_taskPropDict[key] = JSON.parse(dict);
return true;
}
return false;
}

3.4 实现效果

使用缓存前进入页面:

使用缓存后进入页面:

由上图可以看出,使用缓存前进入页面需要请求7个api接口,而缓存了数据之后,进入页面只需要请求3个接口即可,确实起到了减少了请求接口数量的效果。

4. 方案的不足之处及改善

  • 本方案首要的不足在于前端无法准确获知数据库中数据的更新时间。目前暂时设置了缓存时间 expires = 3600 * 1000 ms,也就是说1h内数据被更新了的话,前端显示的依然是缓存的旧数据,这一点暂时没想到改善方法。
  • 此外,缓存使用了 localStorage APIlocalStorage 的特点是只要不手动清除,数据会一直保存在浏览器端,这样用户就没有办法清除缓存,要改善这一点的话可以换一个全局对象(Vuex)来保存数据,只要页面刷新的话,缓存的数据会被清除。
  • 此外,在系统中会有更新这些缓存相关数据的模块,在这些模块中,可以在更新数据之后直接进行缓存数据的清除,等到下次再请求时,程序检查到没有缓存就会直接从服务器请求新的数据,这一定程度改善了前端无法获知数据跟新时间的不足。

前端缓存API请求数据的更多相关文章

  1. 前端向服务器请求数据并渲染的方式(ajax/jQuery/axios/vue)

    原理: jQuery的ajax请求:complete函数一般无论服务器有无数据返回都会显示(成功或者失败都显示数据): return result

  2. h5-localStorage实现缓存ajax请求数据

    使用背景:要实现每次鼠标hover“能力雷达”,则显示能力雷达图(通过ajax请求数据实现雷达图数据显示),所以每次hover都去请求ajax会影响性能,因此这里要用到本地缓存. 实现: 此处是通过传 ...

  3. idea模拟前端向后台请求数据输出响应结果

    tools-httpClient-Test restful web service 通过上述步骤之后出现如下图 1 表示通过哪种方式请求:2 请求数据的地址头部:3 请求数据的除了头部之后的地址:4, ...

  4. 前端常见的请求数据汇总(GET POST)

    前端在请求接口的时候要和后端人员配合好,根据后端提供的接口文档来进行开发,一般请求类型有这几种 1.GET请求 GET请求一般会将数据放到URL后 GET请求对所发信息量的限制是2000个字符 GET ...

  5. 如何实现Echart不刷新页面,多语言切换下的地图数据重新加载,api请求数据加载,soketed数据实时加载

    可视化项目中经常用到ecahrt,各种异步加载,连接socket,多语言切换等问题,现在汇总一下: Ecahrt初始化,全局统一init,可以初始化为0,等待后续数据操作 1.如果是api重新请求,数 ...

  6. 从API请求数据的方法(主要适用于tp5)

    // 从api获取数据,$data是一个数组,默认为空,请求数据的方法可以通用,但是其它说明只适用于tp5 function postData($url,$data=''){ $ch = curl_i ...

  7. python后端从数据库请求数据给到前端的具体实现

    先来贴一窜代码让大家理解前端/后端/数据库的工作原理, 首先简要说明:前端向后端请求数据,后端根据前端请求数据的类别分析其需求,并连接到数据库获取相应数据: 来一段简单的实例代码模拟淘宝商城: 前端代 ...

  8. Web Api 内部数据思考 和 利用http缓存优化 Api

    在上篇<Web Api 端点设计 与 Oauth>后,接着我们思考Web Api 的内部数据: 其他文章:<API接口安全加强设计方法> 第一  实际使用应该返回怎样的数据 ? ...

  9. 微信小程序如何调用API实现数据请求-wx.request()

    前言 微信小程序不存在ajax,那么它是如何实现数据请求功能的呢?在微信中提供了API的调用wx.request(OBJECT),这个是很不错的.下面就讲一下如何请求数据,简单到不行. wx.requ ...

随机推荐

  1. 配置JDK环境及其相关问题

    1.首先找到JDK的安装目录 如果忘记了安装目录在那个地方,可以通过dos命令java -verbose,进行查看 配置jdk环境 新建系统变量JAVA_HOME: 编辑系统变量Path: 新建系统变 ...

  2. Python爬虫系统化学习(2)

    Python爬虫系统学习(2) 动态网页爬取 当网页使用Javascript时候,很多内容不会出现在HTML源代码中,所以爬取静态页面的技术可能无法使用.因此我们需要用动态网页抓取的两种技术:通过浏览 ...

  3. java拼接JSON串

    String str = "{\"route\":\"onGift\",\"time\":\"\",\&quo ...

  4. Java 基础加强 01

    基础加强·网络编程 和 GUI 网络编程概述 * A:计算机网络 * 是指将地理位置不同的具有独立功能的多台计算机及外部设备,通过通信连接起来 在网路操作系统,网络管理软件和网络通信协议的管理下,实现 ...

  5. python引用C++ DLL文件若干解释及示例

    python引用C++ DLL文件若干解释及示例 首先说一下,python不支持C++的DLL,但是支持C的DLL:C++因为和C兼容可以编译为C的DLL,这是下面文章的背景与前提 首先我这儿的示例使 ...

  6. 客官,.NETCore无代码侵入的模型验证了解下

    背景 .NETCore下的模型验证相信绝大部分的.NET开发者或多或少的都用过,微软官方提供的模型验证相关的类位于System.ComponentModel.DataAnnotations命令空间下, ...

  7. LNMP配置——Nginx配置 —— 默认虚拟主机

    一.配置 首先修改配置文件 #vi /usr/local/nginx/conf/nginx.conf 在最后一个结束符号}前加一行配置: include vhost/*.conf; 意思就是/usr/ ...

  8. Apache配置 10. 访问控制-禁止解析PHP

    (1)简述 对于使用PHP语言编写的网站,有一些目录是有需求上传文件的.如果网站代码有漏洞,让黑客上传了一个用PHP写的木马,由于网站可以执行PHP程序,最终会让黑客拿到服务器权限. 为了避免这种情况 ...

  9. git分支管理--rebase&merge详解

    目录 分支合并 git merge --squash [分支名] 注意点 git rebase [分支名] git rebase git rebase --abort git rebase -i gi ...

  10. Android Studio 如何运行单个activity

    •写在前面 调试界面运行单个 Activity 可节省编译整个项目的时间提高效率: 本着提高效率的角度,特地上网百度相关知识: •解决方法 首先,在 AndroidManifest.xml 文件中,找 ...