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 相关文章推荐
不能再简单的无闪刷新验证码原理很简单
Nov 05 Javascript
js中匿名函数的创建与调用方法分析
Dec 19 Javascript
javascript 闭包详解
Feb 15 Javascript
JavaScript每天定时更换皮肤样式的方法
Jul 01 Javascript
javascript数组去重的六种方法汇总
Aug 16 Javascript
深入理解ECMAScript的几个关键语句
Jun 01 Javascript
微信小程序 教程之WXML
Oct 18 Javascript
简单实现js悬浮导航效果
Feb 05 Javascript
angular ng-repeat数组中的数组实例
Feb 18 Javascript
Node.js 中exports 和 module.exports 的区别
Mar 14 Javascript
Angularjs上传图片实例详解
Aug 06 Javascript
Vue 组件传值几种常用方法【总结】
May 28 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的面试题集
2006/11/19 PHP
php强制更新图片缓存的方法
2015/02/11 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
PHP safe_mode开启对于PHP系统函数有什么影响
2020/11/10 PHP
Extjs学习笔记之六 面版
2010/01/08 Javascript
JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
2011/06/28 Javascript
javascript基础知识大全 便于大家学习,也便于我自己查看
2012/08/17 Javascript
js中传递特殊字符(+,&amp;)的方法
2014/01/16 Javascript
使用Sticker.js实现贴纸效果
2015/01/28 Javascript
Redis基本知识、安装、部署、配置笔记
2015/03/05 Javascript
jQuery插件制作之全局函数用法实例
2015/06/01 Javascript
jQuery实现类似淘宝网图片放大效果的方法
2015/07/08 Javascript
JS实现IE状态栏文字缩放效果代码
2015/10/24 Javascript
jQuery Real Person验证码插件防止表单自动提交
2015/11/06 Javascript
jQuery根据name属性进行查找的用法分析
2016/06/23 Javascript
浅谈bootstrap使用中的一些问题以及解决过程
2016/10/18 Javascript
jquery popupDialog 使用 加载jsp页面的方法
2016/10/25 Javascript
nodejs入门教程三:调用内部和外部方法示例
2017/04/24 NodeJs
详解nodeJS之二进制buffer对象
2017/06/03 NodeJs
js实现本地时间同步功能
2017/08/26 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
微信小程序列表时间戳转换实现过程解析
2019/10/12 Javascript
javascript实现简易计算器功能
2020/09/23 Javascript
Python实现修改文件内容的方法分析
2018/03/25 Python
用vue.js组件模拟v-model指令实例方法
2019/07/05 Python
wxpython绘制音频效果
2019/11/18 Python
tensorflow模型的save与restore,及checkpoint中读取变量方式
2020/05/26 Python
Python中SQLite如何使用
2020/05/27 Python
python之openpyxl模块的安装和基本用法(excel管理)
2021/02/03 Python
专注澳大利亚特产和新西兰特产的澳洲中文网:0061澳洲制造
2019/03/24 全球购物
某公司面试题
2012/03/05 面试题
UNIX特点都有哪些
2016/04/05 面试题
2014年党员自我评议对照检查材料
2014/09/20 职场文书
2015年老干部工作总结
2015/04/23 职场文书
2016年9月份红领巾广播稿
2015/12/21 职场文书
pd.DataFrame中的几种索引变换的实现
2022/06/16 Python