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 相关文章推荐
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
Mar 10 Javascript
JS操作Cookies的小例子
Oct 15 Javascript
JavaScript实现存储HTML字符串示例
Apr 21 Javascript
浅谈jQuery页面的滚动位置scrollTop、scrollLeft
May 19 Javascript
简介JavaScript中的sub()方法的使用
Jun 08 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
May 24 Javascript
node.js实现博客小爬虫的实例代码
Oct 08 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
Apr 25 Javascript
Vue2路由动画效果的实现代码
Jul 10 Javascript
使用Three.js实现太阳系八大行星的自转公转示例代码
Apr 09 Javascript
基于Vue el-autocomplete 实现类似百度搜索框功能
Oct 25 Javascript
JS事件循环机制event loop宏任务微任务原理解析
Aug 04 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编写注册后Email激活验证的实例代码
2013/03/11 PHP
解析php中反射的应用
2013/06/18 PHP
PHP实现简单搜歌的方法
2015/07/28 PHP
Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解
2016/03/07 PHP
PHP用户注册邮件激活账户的实现代码
2017/05/31 PHP
PHP多进程编程之僵尸进程问题的理解
2017/10/15 PHP
php中array_fill函数的实例用法
2021/03/02 PHP
Nigma vs Alliance BO5 第四场2.14
2021/03/10 DOTA
Jquery attr(&quot;checked&quot;) 返回checked或undefined 获取选中失效
2013/10/10 Javascript
jquery模拟SELECT下拉框取值效果
2013/10/23 Javascript
框架页面高度自动刷新的Javascript脚本
2013/11/01 Javascript
Jquery+asp.net后台数据传到前台js进行解析的方法
2014/05/11 Javascript
百度地图API之本地搜索与范围搜索
2015/07/30 Javascript
AngularJs验证重复密码的方法(两种)
2016/11/25 Javascript
AngularJS中的Promise详细介绍及实例代码
2016/12/13 Javascript
基于NodeJS+MongoDB+AngularJS+Bootstrap开发书店案例分析
2017/01/12 NodeJs
vue移动端裁剪图片结合插件Cropper的使用实例代码
2017/07/10 Javascript
使用async、enterproxy控制并发数量的方法详解
2018/01/02 Javascript
浅谈vue项目重构技术要点和总结
2018/01/23 Javascript
angular2路由之routerLinkActive指令【推荐】
2018/05/30 Javascript
JavaScript中的this妙用实例分析
2020/05/09 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
2020/05/12 Javascript
Python的Scrapy爬虫框架简单学习笔记
2016/01/20 Python
python 在某.py文件中调用其他.py内的函数的方法
2019/06/25 Python
python实现美团订单推送到测试环境,提供便利操作示例
2019/08/09 Python
Python上下文管理器全实例详解
2019/11/12 Python
带你学习Python如何实现回归树模型
2020/07/16 Python
Python实现中英文全文搜索的示例
2020/12/04 Python
Tuckernuck官网:经典的美国品质服装、鞋子和配饰
2021/01/11 全球购物
技术人员面试提纲
2013/11/28 职场文书
市场营销专业大学生职业生涯规划文
2014/03/06 职场文书
水电站项目建议书
2014/05/12 职场文书
检讨书范文大全
2015/05/07 职场文书
初中运动会前导词
2015/07/20 职场文书
Win11 Build 22000.51版本文件资源管理器“命令栏”和上下文菜单有什么新变化?
2021/11/21 数码科技
利用Python多线程实现图片下载器
2022/03/25 Python