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 相关文章推荐
Node.js生成HttpStatusCode辅助类发布到npm
Apr 09 Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
May 17 Javascript
用RadioButten或CheckBox实现div的显示与隐藏
Sep 21 Javascript
基于javascript滚动图片具体实现
Nov 18 Javascript
JQuery遍历DOM节点的方法
Jun 11 Javascript
js的flv视频播放器插件使用方法
Jun 23 Javascript
利用JS实现数字增长
Jul 28 Javascript
jquery实现多次上传同一张图片
Jan 09 Javascript
利用require.js与angular搭建spa应用的方法实例
Jul 19 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
Jun 19 Javascript
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
Oct 26 jQuery
详解js location.href和window.open的几种用法和区别
Dec 02 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中防止恶意刷新页面的代码小结
2012/10/31 PHP
PHP正确解析UTF-8字符串技巧应用
2012/11/07 PHP
深入apache host的配置详解
2013/06/09 PHP
新浪SAE云平台下使用codeigniter的数据库配置
2014/06/12 PHP
php递归删除指定文件夹的方法小结
2015/04/20 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
PHP实现对图片的反色处理功能【测试可用】
2018/02/01 PHP
php使用fputcsv实现大数据的导出操作详解
2020/02/27 PHP
用Javascript实现锚点(Anchor)间平滑跳转
2009/09/08 Javascript
javascript的函数、创建对象、封装、属性和方法、继承
2011/03/10 Javascript
js中继承的几种用法总结(apply,call,prototype)
2013/12/26 Javascript
jquery遍历select元素(实例讲解)
2013/12/31 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
JS仿iGoogle自定义首页模块拖拽特效的方法
2015/02/13 Javascript
JavaScript、tab切换完整版(自动切换、鼠标移入停止、移开运行)
2016/01/05 Javascript
EasyUi中的Combogrid 实现分页和动态搜索远程数据
2016/04/01 Javascript
JavaScript函数柯里化详解
2016/04/29 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
Vue.js每天必学之表单控件绑定
2016/09/05 Javascript
JavaScript中如何对多维数组(矩阵)去重的实现
2019/12/04 Javascript
javascript设计模式 ? 命令模式原理与用法实例分析
2020/04/20 Javascript
python僵尸进程产生的原因
2017/07/21 Python
python类的实例化问题解决
2019/08/31 Python
python__new__内置静态方法使用解析
2020/01/07 Python
基于pycharm实现批量修改变量名
2020/06/02 Python
Pycharm2020最新激活码|永久激活(附最新激活码和插件的详细教程)
2020/09/29 Python
python 逆向爬虫正确调用 JAR 加密逻辑
2021/01/12 Python
html5跳转小程序wx-open-launch-weapp踩坑
2020/12/02 HTML / CSS
办公室副主任职责范本
2014/03/08 职场文书
文秘个人求职信范文
2014/04/22 职场文书
房地产公司见习自我鉴定
2014/04/28 职场文书
法人授权委托书样本
2014/09/19 职场文书
搞笑婚前保证书
2015/02/28 职场文书
2015年八一建军节慰问信
2015/03/23 职场文书
HTML中table表格拆分合并(colspan、rowspan)
2021/04/07 HTML / CSS
Java实现贪吃蛇游戏的示例代码
2022/09/23 Java/Android