js使用Promise实现简单的Ajax缓存


Posted in Javascript onNovember 14, 2018

业务场景

在不少业务场景下,我们需要实现简单的请求缓存(即某个请求只发起一次请求),例如上传 Token 的获取、获取配置的接口等。

这些接口可以通过 Promise 实现简单的缓存并能够控制更新,而不需要另外引入缓存层。

示范代码

用七牛上传作例子,一般我们会把七牛上传封装为一个单独的 Upload 组件,外部只需要调用组件,而 token 的获取封装到组件内部实现。

//Upload.vue
let fetchToken = null;
export default {
 data() {
  return {
   token: ''
  };
 },
 methods: {
  async upload() {
   try {
    // ...
   }
   catch(err) {
    alert(err.message);
    this.refreshToken();
   }
  },
  refreshToken() {
   fetchToken = null;
   this.fetchToken();
  },
  fetchToken() {
   if (!fetchToken) {
    fetchToken = request.get('/api/qiniu/token');
   }
   try {
    this.token = await fetchToken;
   }
   catch(err) {
    console.error(err);
   }
  }
 },
 created() {
  this.fetchToken();
 }
};

上面是一个简单的缓存上传 token 的例子,并且会在上传失败时刷新 token。

与直接缓存 Token 的值比较,缓存请求有什么好处?

// 缓存值的代码
export default {
 methods: {
  fetchToken() {
   if (!fetchToken) {
    fetchToken = await request.get('/api/qiniu/token');
   }
   try {
    this.token = fetchToken;
   }
   catch(err) {
    console.error(err);
   }
  }
 }
}

一个比较常见的 Upload 组件 的应用场景,在一个页面里同时使用多次该组件。

<template>
 <div class="upload1"><upload /></div>
 <div class="upload2"><upload /></div>
</template>

就上面的代码例子,如果使用缓存值的方法,那么页面一打开就会请求两次获取 Token 接口。

继续完善 Upload 组件

//Upload.vue
let fetchToken = null;
export default {
 methods: {
  async upload() {
   try {
    this.fetchToken();
    const token = await fetchToken;
    // ...
   } catch (err) {
    alert(err.message);
    this.refreshToken();
   }
  },
  refreshToken() {
   fetchToken = null;
   this.fetchToken();
  },
  fetchToken() {
   if (!fetchToken) {
    fetchToken = request.get('/api/qiniu/token');
   }
  }
 },
 created() {
  this.fetchToken();
 }
};

为了防止多个 Upload 组件 token 不同步问题,不再通过this.token保存 token,而是每次都等待 fetchToken resolved,保证获取到的 token 一定是最新的。

当然,这里还有很多需要优化,例如失败后的重试、判断是 401 失败才刷新 token、设置错误时间、定时刷新等等,但总体思路就是上面代码所展示的内容。

另外再介绍一个经典应用场景

const fetchConfig = (() => {
 let configRequest = null;
 return () => {
  if (!configRequest) {
   configRequest = Promise.all([services.customer.config1, services.customer.config2])
    .then(([data1, data2]) => {
     return { data1, data2 };
    })
    .catch(err => {
     configRequest = null;
     return Promise.reject(err);
    });
  }
  return configRequest;
 };
})();

export default {
 async beforeRouteEnter(to, from, next) {
  try {
   // 配置信息仅需要成功请求一次
   const [data, config] = await Promise.all([services.customer.getInfo(), fetchConfig()]);
   next(vm => {
    vm.data = data;
    vm.config = config;
    vm.init();
   };
  } catch (err) {
   next(err);
  }
 }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js小技巧--自动隐藏红叉叉
Aug 13 Javascript
Wordpress ThickBox 点击图片显示下一张图的修改方法
Dec 11 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
Jan 15 Javascript
javascript获取隐藏元素(display:none)的高度和宽度的方法
Jun 06 Javascript
AngularJS入门知识之MVW类框架的编程思想探讨
Dec 08 Javascript
javascript中offset、client、scroll的属性总结
Aug 13 Javascript
在React框架中实现一些AngularJS中ng指令的例子
Mar 06 Javascript
Node.js返回JSONP详解
May 18 Javascript
Bootstrap datepicker日期选择器插件使用详解
Jul 26 Javascript
分析JavaScript数组操作难点
Dec 18 Javascript
微信公众平台 客服接口发消息的实现代码(Java接口开发)
Apr 17 Javascript
微信小程序实现手势滑动卡片效果
Aug 26 Javascript
微信jssdk逻辑在vue中的运用详解
Nov 14 #Javascript
Puppeteer 爬取动态生成的网页实战
Nov 14 #Javascript
React和Vue中监听变量变化的方法
Nov 14 #Javascript
详解jQuery获取特殊属性的值以及设置内容
Nov 14 #jQuery
浅谈vue中关于checkbox数据绑定v-model指令的个人理解
Nov 14 #Javascript
js html实现计算器功能
Nov 13 #Javascript
JavaScript使用类似break机制中断forEach循环的方法
Nov 13 #Javascript
You might like
PHP语言中global和$GLOBALS[]的分析 之二
2012/02/02 PHP
JoshChen_web格式编码UTF8-无BOM的小细节分析
2013/08/16 PHP
PHP基于ICU扩展intl快速实现汉字转拼音及按拼音首字母分组排序的方法
2017/05/03 PHP
jquery简单体验
2007/01/10 Javascript
解决js正则匹配换行问题实现代码
2012/12/10 Javascript
JQuery入门——移除绑定事件unbind方法概述及应用
2013/02/05 Javascript
Jquery获取元素的父容器对象示例代码
2014/02/10 Javascript
JavaScript中对循环语句的优化技巧深入探讨
2014/06/06 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 语法
2015/01/09 Javascript
js实现DOM走马灯特效的方法
2015/01/21 Javascript
jQuery的bind()方法使用详解
2015/07/15 Javascript
基于jquery实现省市区三级联动效果
2015/12/25 Javascript
jQuery模拟实现的select点击选择效果【附demo源码下载】
2016/11/09 Javascript
实例浅析js的this
2016/12/11 Javascript
bootstrap导航栏、下拉菜单、表单的简单应用实例解析
2017/01/06 Javascript
bootstrap fileinput 插件使用项目总结(经验)
2017/02/22 Javascript
jQuery EasyUI Accordion可伸缩面板组件使用详解
2017/02/28 Javascript
jquery基于layui实现二级联动下拉选择(省份城市选择)
2017/06/20 jQuery
利用Webpack实现小程序多项目管理的方法
2019/02/25 Javascript
通过微信公众平台获取公众号文章的方法示例
2019/12/25 Javascript
Vue为什么要谨慎使用$attrs与$listeners
2020/08/27 Javascript
[01:15:56]2018DOTA2亚洲邀请赛3月30日 小组赛A组 TNC VS Newbee
2018/03/31 DOTA
[46:42]DOTA2-DPC中国联赛正赛 Aster vs Magma BO3 第二场 3月5日
2021/03/11 DOTA
python字典get()方法用法分析
2015/04/17 Python
Pycharm学习教程(6) Pycharm作为Vim编辑器使用
2017/05/03 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
FFrpc python客户端lib使用解析
2019/08/24 Python
10个最常见的HTML5面试题 附答案
2016/06/06 HTML / CSS
h5使用canvas画布实现手势解锁
2019/01/04 HTML / CSS
Allsole美国/加拿大:英国一家专门出售品牌鞋子的网站
2018/10/21 全球购物
全运会口号
2014/06/20 职场文书
村主任个人对照检查材料
2014/10/01 职场文书
工人先锋号申报材料
2014/12/29 职场文书
2015年普法依法治理工作总结
2015/05/26 职场文书
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫
Pandas实现批量拆分与合并Excel的示例代码
2022/05/30 Python