vue项目中axios取消请求

676 阅读2分钟

在开发过程中,遇到了下面的场景:

1、当切换tab的时候,前一个tab页的请求还在pending时,切换到了第二个tab,前一个tab页数据量大,还未响应,但是第二个tab页的请求先响应了,过一会前一个tab页的请求响应了,导致用户处于第二个tab页但是数据是前一个tab页的。

2、局部分页的功能,请求第二页数据又很快请求第三页时,如果网络不太稳定时或者数据量过大也会出现以上的现象


针对数据错乱的现象 我们应当是在做下一步操作之前,杀掉正在pending的请求。

axios取消请求

官方文档:www.axios-js.com/zh-cn...

Axios 的 cancel token API 基于cancelable promises proposal,它还处于第一阶段。

从官方文档中可以看出axios取消请求主要分为两个步骤:

1.axios.CancelToken生成实例、注册cancel函数、请求时携带cancelToken参数(与url平级)

2.调用cancel方法取消请求

使用mixin封装取消请求的功能

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

新建mixin文件 : /mixins/cancelToken.js 封装取消请求功能代码

import axios from 'axios';
const CancelToken = axios.CancelToken;
​
const cancelTokenMixin = {
    data() {
      return {
        cancelToken: null, // cancelToken实例
        cancel: null // cancel方法
      }
    },
    created() {
      this.newCancelToken();
​
    },
    beforeDestroy() {
      //离开页面前清空所有请求
      this.cancel('取消请求');
    },
    methods: {
      //创建新CancelToken
      newCancelToken() {
        this.cancelToken = new CancelToken(c => {
            this.cancel = c;
        });
      }
    }
}
export default cancelTokenMixin;

在具体做操作的vue文件里引入mixin,然后:在请求之前取消上次请求并且创建新的cancelToken

例:切换tab栏

import cancelTokenMixin from "@/utils/cancelToken";
import getTabList from '@/api/Tablist';
​
mixins: [cancelTokenMixin],
​
methods:{
    //切换tab标签, id为不同的tab标签的标识
   changeTab(id){
      //取消上一次请求
      this.cancel("操作取消");
      //使用新的cancelToken
      this.newCancelToken();
      this.getTabList(id);
   },
   getTabList(type){
       let data ={tab:type},//需要传的参数
       getTabList(data,{ cancelToken: this.cancelToken }).then(res=>{}).catch(err=>{})
   }
}
​

api/Tablist.js文件:在需要做取消pending的请求里新增接受cancelToken配置参数,也就是接受两个参数,一个是请求参数,一个是配置参数config,也就是上面这个:{ cancelToken: this.cancelToken }

import axios from "./http"; // 导入http中创建的axios实例export function getTabList(data, config) {
    return axios({
        url: 'api/getALLTabLink',
        method: 'post',
        data,
        ...config
    })
}