如何取消axios请求

·  阅读 972

如何取消axios请求

八月更文第四弹, 开始啦! 🍦

这是我参与8月更文挑战的第4天,如果你遇到一个场景,请求上万的分页数据,在请求一半的时候需要停止请求。或者在请求一半时切换了选项,开始另一个请求。
不论是以上哪种场景,都会涉及到一个问题,那就是如何取消掉axios的请求。说到取消其实很简单设置cancelToken就可以了。但是我们实际使用中可能会更复杂,需要取消指定url的axios请求,这时候要怎么办呢

axios 配置

要实现以上需求,首先要做的依旧是在axios中封装cancel

  // 请求拦截器 添加token, 判断登录之类操作
  instance.interceptors.request.use(
    config => {

      // 判断请求中是否还有非pending的同类
      config.cancelToken = new CancelToken(c => {
        cancel = c
        let str = url.split('/')
        str = Array.from(new Set(str))
        let index = str.length - 1
        let funName = str[index]
        store.dispatch('request/setCancel', { cancel, funName: funName })
      })

      return config
    },
    error => {
      return Promise.reject(error)
    }
  )
    // 响应拦截器,对返回数据进行预处理
  instance.interceptors.response.use(
    response => {

      // 判断响应中是否还有非pending的同类
      removePendingAjax(response.config)
      store.dispatch('request/response', response.config.url)

      return response
    },
    error => {
        return Promise.reject(error)
    }
  )
复制代码

设置vuex存储url

在vuex中存储请求的url

export default {
  namespaced: true,
  state: {
    cancel: {}
  },

  mutations: {
    CANCEL(state, { funNames = [], msg = '' }) {
      if (!Object.keys(state.cancel).length) {
        return false
      }
      for (const key in state.cancel) {
        // eslint-disable-next-line no-prototype-builtins
        if (state.cancel.hasOwnProperty(key)) {
          if (funNames.includes(key)) {
            if (!state.cancel[key].response) {
              state.cancel[key].cancel(msg)
              state.cancel[key].response = true
            }
          }
        } else {
          return false
        }
      }
    },
    SET_CANCEL(state, { cancel, funName }) {
      state.cancel[funName] = { cancel, response: false }
    },
    RESPONSE(state, funName) {
      if (Object.keys(state.cancel).includes(funName)) {
        state.cancel[funName].response = true
      }
    }
  },

  actions: {
    setCancel({ commit }, fn) {
      commit('SET_CANCEL', fn)
    },
    response({ commit }, res) {
      commit('RESPONSE', res)
    },
    cancel({ commit }, res) {
      commit('CANCEL', res)
    }
  }
}

// 用法: this.$store.dispatch('request/cancel', { funNames: ['当前url地址'] })

复制代码

在指定页面使用

在指定页面使用取消当前axios请求
例如在更改合同时我们要断掉未请求完的数据,就要在切换时进行中断axios,name必须获取完整参数,同请求url对比。

// 更改合同
selectChange(e) {
  let name = `pageList?contractId=${this.contractId}&queryDate=${this.queryParams}&currentPage=${this.currentPage}&pageSize=${this.pageSize}`
  this.$store.dispatch('request/cancel', { funNames: [name] })
  // ...
},
复制代码

axios官网取消方法

使用 CancelToken.source 工厂方法创建 cancel token:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});

axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
复制代码

传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

const CancelToken = axios.CancelToken;
let cancel;

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

// cancel the request
cancel();
复制代码

总结

本文到此结束,希望对你有帮助 😉

分类:
前端