继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Vue踩坑日记之cancelToken

BIG阳
关注TA
已关注
手记 474
粉丝 73
获赞 458

在真实项目中,当路由已经跳转,而上一页的请求还在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


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP