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和JQuery实用代码片段(一)
Apr 07 Javascript
jQuery使用toggleClass方法动态添加删除Class样式的方法
Mar 26 Javascript
jQuery Validation PlugIn的使用方法详解
Dec 18 Javascript
分享jQuery网页元素拖拽插件
Dec 01 Javascript
js遍历map javaScript遍历map的简单实现
Aug 26 Javascript
微信小程序 wxapp视图容器 view详解
Oct 31 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
Apr 18 Javascript
AngularJS实现的回到顶部指令功能实例
May 17 Javascript
jQuery Validate插件ajax方式验证输入值的实例
Dec 21 jQuery
简化vuex的状态管理方案的方法
Jun 02 Javascript
详解jenkins自动化部署vue
May 14 Javascript
关于vue属性使用和不使用冒号的区别说明
Oct 22 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 获取select下拉列表框的值
2010/05/08 PHP
PHPUnit PHP测试框架安装方法
2011/03/23 PHP
php_screw 1.5:php加密: 安装与使用详解
2013/06/20 PHP
jquery $.ajax()取xml数据的小问题解决方法
2010/11/20 Javascript
使用documentElement正确取得当前可见区域的大小
2014/07/25 Javascript
thinkphp实现无限分类(使用递归)
2015/12/19 Javascript
jQuery解决浏览器兼容性问题案例分析
2016/04/15 Javascript
从重置input file标签中看jQuery的 .val() 和 .attr(“value”) 区别
2016/06/12 Javascript
jQuery实现的右下角广告窗体跟随效果示例
2016/09/16 Javascript
react.js 翻页插件实例代码
2017/01/19 Javascript
javascript笔记之匿名函数和闭包
2017/02/06 Javascript
jQuery插件MovingBoxes实现左右滑动中间放大图片效果
2017/02/28 Javascript
浅谈express 中间件机制及实现原理
2017/08/31 Javascript
NodeJs form-data格式传输文件的方法
2017/12/13 NodeJs
vue-devtools的安装步骤
2018/04/23 Javascript
npm配置国内镜像资源+淘宝镜像的方法
2018/09/07 Javascript
浅谈angular表单提交中ng-submit的默认使用方法
2018/09/30 Javascript
Django+Vue实现WebSocket连接的示例代码
2019/05/28 Javascript
vuex+axios+element-ui实现页面请求loading操作示例
2020/02/02 Javascript
原生小程序封装跑马灯效果
2020/10/21 Javascript
python操作sqlite的CRUD实例分析
2015/05/08 Python
python读取word文档的方法
2015/05/09 Python
Python 基于Twisted框架的文件夹网络传输源码
2016/08/28 Python
python对DICOM图像的读取方法详解
2017/07/17 Python
python logging日志模块原理及操作解析
2019/10/12 Python
python实现超市商品销售管理系统
2019/10/25 Python
Python使用20行代码实现微信聊天机器人
2020/06/05 Python
python-地图可视化组件folium的操作
2020/12/14 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
浅析几个CSS3常用功能的写法
2014/06/05 HTML / CSS
GAZMAN官网:澳大利亚领先的男装品牌
2019/12/19 全球购物
世界经理人咨询有限公司面试
2014/09/23 面试题
欢迎标语大全
2014/06/21 职场文书
中秋节活动总结
2014/08/29 职场文书
《狼王梦》读后感:可怜天下父母心
2019/11/01 职场文书
详解CSS玩转图片Base64编码
2021/05/25 HTML / CSS