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 相关文章推荐
Google Suggest ;-) 基于js的动态下拉菜单
Oct 11 Javascript
页面中body onload 和 window.onload 冲突的问题的解决
Jul 01 Javascript
javascript变量作用域使用中常见错误总结
Mar 26 Javascript
JQuery操作单选按钮以及复选按钮示例
Sep 23 Javascript
JS获取单击按钮单元格所在行的信息
Jun 17 Javascript
jQuery动态添加
Apr 07 Javascript
jquery实现焦点轮播效果
Feb 23 Javascript
jQueryeasyui 中如何使用datetimebox 取两个日期间相隔的天数
Jun 13 jQuery
jquery点击回车键实现登录效果并默认焦点的方法
Mar 09 jQuery
js+canvas实现验证码功能
Sep 21 Javascript
Vue移动端项目实现使用手机预览调试操作
Jul 18 Javascript
JS addEventListener()和attachEvent()方法实现注册事件
Jan 11 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
BBS(php &amp; mysql)完整版(三)
2006/10/09 PHP
PHP实现用户认证及管理完全源码
2007/03/11 PHP
php部分常见问题总结
2008/03/27 PHP
php常见的魔术方法详解
2014/12/25 PHP
smarty自定义函数用法示例
2016/05/20 PHP
PHP判断表达式中括号是否匹配的简单实例
2016/10/22 PHP
PHP面向对象之工作单元(实例讲解)
2017/06/26 PHP
使用php自动备份数据库表的实现方法
2017/07/28 PHP
php实现构建排除当前元素的乘积数组方法
2018/10/06 PHP
laravel5.1框架基础之Blade模板继承简单使用方法分析
2019/09/05 PHP
用倒置滤镜把div倒置,再把table倒置。
2007/07/31 Javascript
js setattribute批量设置css样式
2009/11/26 Javascript
用javascript模仿ie的自动完成类似自动完成功的表单
2012/12/12 Javascript
js类式继承的具体实现方法
2013/12/31 Javascript
jquery datatable后台封装数据示例代码
2014/08/07 Javascript
js 弹出虚拟键盘修改密码的简单实例
2016/10/10 Javascript
jquery checkbox的相关操作总结
2016/10/17 Javascript
jQuery UI插件实现百度提词器效果
2016/11/21 Javascript
Vue-Router实现页面正在加载特效方法示例
2017/02/12 Javascript
bootstrap suggest搜索建议插件使用详解
2017/03/25 Javascript
解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)
2018/07/26 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
vue下使用nginx刷新页面404的问题解决
2019/08/02 Javascript
Node.js API详解之 V8模块用法实例分析
2020/06/05 Javascript
利用JS判断元素是否为数组的方法示例
2021/01/08 Javascript
对于Python的Django框架部署的一些建议
2015/04/09 Python
python 遍历目录(包括子目录)下所有文件的实例
2018/07/11 Python
Django 实现购物车功能的示例代码
2018/10/08 Python
python单线程文件传输的实例(C/S)
2019/02/13 Python
浅析python的Lambda表达式
2019/02/27 Python
python多线程抽象编程模型详解
2019/03/20 Python
python可视化篇之流式数据监控的实现
2019/08/07 Python
HTML利用九宫格原理进行网页布局
2020/03/13 HTML / CSS
澳大利亚领先的在线美容商店:Facial Co
2017/10/22 全球购物
意大利折扣和优惠券网站:Groupalia
2019/10/09 全球购物
艺术设计专业求职自荐信
2014/05/19 职场文书