axios取消请求

1,220 阅读1分钟

背景

目前项目有2种情景需要取消请求

  • 组件销毁时,取消请求
  • 列表查询时,多次点击查询(每次查询条件不一样),最后一次查询很快,最终结果会被之前查询结果覆盖掉

解决方案:Axios 的 cancel token API

上面2种情况都是使用axios的cancel token API解决的,不过写法略有不同

组件销毁,取消请求

简单例子

const CancelToken = axios.CancelToken;
let cancel;

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

// 取消请求
cancel()

vue使用mixin取消请求

// cancelTokenMixin.js

import axios from 'axios';

const CancelToken = axios.CancelToken;

const cancelTokenMixin = {
  data () {
    return {
      cancelToken: null, // cancelToken实例
      cancel: null // cancel方法
    };
  },

  created () {
    // 初始化生成cancelToken实例,注册cancel方法
    this.cancelToken = new CancelToken(c => {
      this.cancel = c;
    });
  },

  beforeDestroy () {
    // 组件销毁阶段调用cancel方法取消请求
    this.cancel(`${this.pageName}取消请求`);
  }
};

export default cancelTokenMixin;
// DataManage.vue

import cancelTokenMixin from '../mixin/cancelTokenMixin'

export default {
  name: 'DataManage',
  mixins: [cancelTokenMixin], // 引入mixin
  data () {
    ....
  },
  mounted () {
    this.getData()
  },
  method: {
    getData () {
      this.loading = true
      // 请求携带cancelToken参数
      axios.get('http://localhost:7000/data', { cancelToken: this.cancelToken }).then(res => {
        const data = res.data
        if (data.success) {
          this.allData = data.fruits
          this.changePage()
        }
      }).catch(err => {
        const message = err.message || '获取数据失败';
        console.log(message);
        this.$message({
          type: 'error',
          message
        })
      }).finally(() => {
        this.loading = false
      })
    },
    ....
  }

详细说明请参考原文链接:juejin.cn/post/684490…

多次点击查询,取消请求

    import axios from 'axios'
    const CancelToken = axios.CancelToken
    
    data(){
        cancel:null
    },
    
    // 多次触发getList请求 取消上次请求,触发最新请求
    async getList() {
        if(cancel != null) {
            cancel()
        }
        let res = await axios.post('/user/list', {
            name: xxx
        }, {
            cancelToken: new CancelToken(c => {
                cancel = c
            })
        })
        cancel = null
    }

这里就不写mixin做法了,参考上面,抽离相关逻辑即可