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 EasyPager 分页函数
May 25 Javascript
基于jquery的web页面日期格式化插件
Nov 15 Javascript
防止文件缓存的js代码
Jan 10 Javascript
jQuery+HTML5+CSS3制作支持响应式布局时间轴插件
Aug 10 Javascript
js获取Get值的方法
Sep 29 Javascript
jQuery向webApi提交post json数据
Jan 16 Javascript
jQuery弹出层插件popShow用法示例
Jan 23 Javascript
动态创建Angular组件实现popup弹窗功能
Sep 15 Javascript
VueJs 将接口用webpack代理到本地的方法
Nov 27 Javascript
微信小程序实现图片滚动效果示例
Dec 05 Javascript
vue多个元素的样式选择器问题
Nov 29 Javascript
javascript实现点击星星小游戏
Dec 24 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 在字符串指定位置插入新字符的简单实现
2016/06/28 PHP
Yii2创建控制器(createController)方法详解
2016/07/23 PHP
PHP读MYSQL中文乱码的快速解决方法
2016/10/01 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
2018/12/07 PHP
PHP生成随机密码4种方法及性能对比
2020/12/11 PHP
PHP操作Redis常用命令的实例详解
2020/12/23 PHP
php的对象传值与引用传值代码实例讲解
2021/02/26 PHP
JavaScript中圆括号()和方括号[]的特殊用法疑问解答
2013/08/06 Javascript
使用javascript实现ListBox左右全选,单选,多选,全请
2013/11/07 Javascript
JS控制表格实现一条光线流动分割行的方法
2015/03/09 Javascript
js实现带农历和八字等信息的日历特效
2016/05/16 Javascript
Java中int与integer的区别(基本数据类型与引用数据类型)
2017/02/19 Javascript
js 获取今天以及过去日期
2017/04/11 Javascript
JS实现图片点击后出现模态框效果
2017/05/03 Javascript
详解vue中的computed的this指向问题
2018/12/05 Javascript
小程序:授权、登录、session_key、unionId的详解
2019/05/15 Javascript
微信小程序中如何计算距离某个节日还有多少天
2019/07/15 Javascript
小程序实现简单语音聊天的示例代码
2020/07/24 Javascript
[02:22]《新闻直播间》2017年08月14日
2017/08/15 DOTA
Python 26进制计算实现方法
2015/05/28 Python
Python多线程爬虫实战_爬取糗事百科段子的实例
2017/12/15 Python
Python如何爬取实时变化的WebSocket数据的方法
2019/03/09 Python
Django使用redis缓存服务器的实现代码示例
2019/04/28 Python
pygame编写音乐播放器的实现代码示例
2019/11/19 Python
Python实现i人事自动打卡的示例代码
2020/01/09 Python
Python3 hashlib密码散列算法原理详解
2020/03/30 Python
解析python 类方法、对象方法、静态方法
2020/08/15 Python
详解tf.device()指定tensorflow运行的GPU或CPU设备实现
2021/02/20 Python
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
某某同志考察材料
2014/05/28 职场文书
学校安全教育月活动总结
2014/07/07 职场文书
体育专业求职信
2014/07/16 职场文书
2015年公路养护工作总结
2015/05/13 职场文书
同意报考公务员证明
2015/06/17 职场文书
如何撰写出一份完美的商业计划书?
2019/07/12 职场文书
Tomcat 与 maven 的安装与使用教程
2022/06/16 Servers