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 相关文章推荐
javascript实现二分查找法实现代码
Nov 12 Javascript
node.js中的buffer.Buffer.isEncoding方法使用说明
Dec 14 Javascript
node.js中的buffer.copy方法使用说明
Dec 14 Javascript
JS实现的文字与图片定时切换效果代码
Oct 06 Javascript
Javascript的无new构建实例详解
May 15 Javascript
你知道setTimeout是如何运行的吗?
Aug 16 Javascript
火狐和ie下获取javascript 获取event的方法(推荐)
Nov 26 Javascript
AngularJS实现页面定时刷新
Mar 14 Javascript
create-react-app修改为多页面支持的方法
May 17 Javascript
微信小程序购物车、父子组件传值及calc的注意事项总结
Nov 14 Javascript
浅谈Node新版本13.2.0正式支持ES Modules特性
Nov 25 Javascript
JavaScript实现队列结构过程
Dec 06 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
Mysql的GROUP_CONCAT()函数使用方法
2008/03/28 PHP
php在页面中调用fckeditor编辑器的方法
2011/06/10 PHP
php数据结构与算法(PHP描述) 查找与二分法查找
2012/06/21 PHP
基于curl数据采集之单页面采集函数get_html的使用
2013/04/28 PHP
PHP中的日期加减方法示例
2014/08/21 PHP
PHP实现加密的几种方式介绍
2015/02/22 PHP
PHP SPL标准库之SplFixedArray使用实例
2015/05/12 PHP
js null,undefined,字符串小结
2010/08/21 Javascript
神奇的7个jQuery 3D插件整理
2011/01/06 Javascript
js跨浏览器实现将字符串转化为xml对象的方法
2013/09/25 Javascript
jQuery实现行文字链接提示效果的方法
2015/03/10 Javascript
Jquery日历插件制作简单日历
2015/10/28 Javascript
简单的jQuery banner图片轮播实例代码
2016/03/04 Javascript
jQuery实现滚动鼠标放大缩小图片的方法(附demo源码下载)
2016/03/05 Javascript
js实现String.Fomat的实例代码
2016/09/02 Javascript
表单元素值获取方式js及java方式的简单实例
2016/10/15 Javascript
微信小程序 wxapp内容组件 text详细介绍
2016/10/31 Javascript
element-ui使用导航栏跳转路由的用法详解
2018/08/22 Javascript
vue select选择框数据变化监听方法
2018/08/24 Javascript
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
2018/11/28 Javascript
详解在React项目中安装并使用Less(用法总结)
2019/03/18 Javascript
vue+elementUI 复杂表单的验证、数据提交方案问题
2019/06/24 Javascript
Js利用正则表达式去除字符串的中括号
2020/11/23 Javascript
[05:17]DOTA2睡衣妹卖萌求签名 CJ第二天全明星影像
2013/07/28 DOTA
Python读取一个目录下所有目录和文件的方法
2016/07/15 Python
Python实现将一个大文件按段落分隔为多个小文件的简单操作方法
2017/04/17 Python
利用aardio给python编写图形界面
2017/08/21 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
Python 实现进度条的六种方式
2021/01/06 Python
海量信息软件测试笔试题
2015/08/08 面试题
风险评估实施方案
2014/03/09 职场文书
企业元宵节主持词
2014/03/25 职场文书
2014年个人工作总结范文
2014/11/07 职场文书
学生早退检讨书(范文)
2019/08/19 职场文书
Python图片验证码降噪和8邻域降噪
2021/08/30 Python
mysqldump进行数据备份详解
2022/07/15 MySQL