为了账号安全,请及时绑定邮箱和手机立即绑定

Vue踩坑日记之cancelToken

标签:
Vue.js

在真实项目中,当路由已经跳转,而上一页的请求还在pending状态,如果数据量小还好,数据量大时,跳到新页面,旧的请求依旧没有停止,这将会十分损耗性能,这时我们应该先取消掉之前还没有获得相应的请求,再跳转页面。这里axios给我们提供了一个方法:

cancelToken

让我们来看看cancelToken的使用方法:

官网方法一:var CancelToken = axios.CancelToken;var source = CancelToken.source();

axios.get('/user/12345', {  cancelToken: source.token
}).catch(function(thrown) {  if (axios.isCancel(thrown)) {    console.log('Request canceled', thrown.message);
  } else {    // 处理错误
  }
});// 取消请求(message 参数是可选的)source.cancel('Operation canceled by the user.');

如果我要跳转页面的话,我调用source.cance()方法就可以干掉之前这个没有请求完的请求了。
但是这个方法有个弊端,就是比较麻烦,每次都要手动去调用source.cance()方法。怎么做到全局统一管理呢?

官网给了以下方法:

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

var CancelToken = axios.CancelToken;var cancel;

axios.get('/user/12345', {  cancelToken: new CancelToken(function executor(c) {    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});// 取消请求cancel();

根据这个方法:我们一步一步来实现它:
在main.js里写一个全局httpRequestList的空数组,用来装我们的cancel函数:

// main.jsVue.$httpRequestList = []

再在我们封装好的post,get请求里面,将每一个请求里面都做一个将cancel函数推入的httpRequestList数组的动作:

POST (url, data, errMsg) {    const CancelToken = axios.CancelToken    return axios.post(url, data, {      timeout: 30000,      cancelToken: new CancelToken(function executor (c) {
        Vue.$httpRequestList.push(c)
      })
    }).then(checkStatus).then(res => checkCode(res, errMsg))
  },
  GET (url, params, errMsg) {    const CancelToken = axios.CancelToken    return axios.get(url, {      params: {        _t: +(new Date()),
        ...params
      },      timeout: 30000,      cancelToken: new CancelToken(function executor (c) {
        Vue.$httpRequestList.push(c)
      })
    }).then(checkStatus).then(res => checkCode(res, errMsg))
  }

这样我们的每一个请求里面,都包含了一个cancelToken对象。

在这之后我们要写一个执行cancel方法的 方法:

import Vue from 'vue'export const clearHttpRequestingList = () => {  if (Vue.$httpRequestList.length > 0) {
    Vue.$httpRequestList.forEach((item) => {
      item()
    })
    Vue.$httpRequestList = []
  }
}

item就是之前每一个请求装进httpRequestList数组的cancel方法,item()执行后,如果该请求是pending状态,那么可以直接取消掉。执行完后记得清空httpRequestList数组。

最后我们回到main.js
在每次跳转之前执行clearHttpRequestingList()函数。

router.beforeEach((to, from, next) => {
  clearHttpRequestingList()
  ..........这下面是你的路由验证代码..........
})

这样就实现了每次路由跳转之前,就清空之前出于pending状态的请求,优化了性能。
如下图所示:


webp

             




作者:alex夏夜
链接:https://www.jianshu.com/p/42d1c58e785e


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消