经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
前端缓存API请求数据
来源:cnblogs  作者:袁艺明  时间:2021/5/6 17:57:48  对本文有异议

1. 背景

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

2. 实现思路

主要有以下3个步骤:

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

3. 具体实现

3.1 初次获取数据

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

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

3.2 建立映射表,缓存数据

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

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

3.3 查找缓存数据

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

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

3.4 实现效果

使用缓存前进入页面:

使用缓存后进入页面:

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

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

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

原文链接:http://www.cnblogs.com/yuanyiming/p/14706224.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号