axios多个请求,中断前面的请求,保留最后一个

有时候我们常常在发起一个请求时,希望取消前面的一个或多个请求,就要使用axios的一个方法CancelToken(), 配置方法如下。

第一种方法,使用CancelToken.source工厂创建一个取消令牌:

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 {
    // 处理错误
  }
});
//取消请求(消息参数是可选的)
source.cancel('操作被用户取消。');

第二种方法,我们可以在拦截器里统一处理取消重复请求


import axios from "axios";
 
window.axiosCancel = []  // 全局定义一个存放取消请求的标识
//请求前拦截
Axios.interceptors.request.use(config => {
    return config
    // 添加取消标记
    config.cancelToken = new axios.CancelToken(cancel => {
        window.axiosCancel.push({
        cancel
    })
 
},function(error) {
    return Promise.reject(error)
});
 
//请求后返回数据拦截
Axios.interceptors.response.use(res => {
        
},function axiosRetryInterceptor(res) {
    return Promise.reject(res )
});
export default Axios

然后在组件中使用,发送一个新的请求之前,取消前面的所有正在请求的请求,如下:

methods:{
    cancel(){ // 设置一个函数,在执行请求前先执行这个函数
        // 获取缓存的 请求取消标识 数组,取消所有关联的请求
        let cancelArr = window.axiosCancel;
        cancelArr.forEach((ele, index) => {
            ele.cancel("取消了请求") // 在失败函数中返回这里自定义的错误信息
            delete window.axiosCancel[index]
        })
    },
    getList(){
        this.cancel()   // 取消所有正在发送请求的请求
        axios.post(..)  // 发送一个新的请求
    }
}

如果不希望每个组件里面都定义一个cancel函数,我们可以把这个函数挂载到vue实例的原型上,这样就可以在任何组件中使用cancel函数了:this.cancel(),如下main.js文件中:


import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'//引入store
Vue.config.productionTip = false
 
// 将cancel,挂载到vue原型上
Vue.prototype.cancel = function(){
    // 获取缓存的 请求取消标识 数组,取消所有关联的请求
    let cancelArr = window.axiosCancel || [];
    cancelArr.forEach((ele, index) => {
        ele.cancel("取消了请求")  // 在失败函数中返回这里自定义的错误信息
        delete window.axiosCancel[index]
    })
}
 
window.vm=new Vue({
  el: '#app',
  data(){
    return{
    }
  },
  router,
  store,
  components: { App },
})

另外如果想每次路由页面跳转时,取消上一个页面的所有请求,我们可以把cancel()函数的内容放在路由拦截器中,router/index.js文件配置,如下:


/* 路由拦截器 路由跳转前的操作 */
router.beforeEach((to, from, next) => {
    // 获取缓存的 请求取消标识 数组,取消所有关联的请求
    let cancelArr = window.axiosCancel;
    cancelArr.forEach((ele, index) => {
        ele.cancel("取消了请求")  // 在失败函数中返回这里自定义的错误信息
        delete window.axiosCancel[index]
    })
    next()
})

原文链接:https://blog.youkuaiyun.com/qq_41772754/article/details/88258051

在封装的 Axios 接口中实现请求中断,通常通过 Axios 提供的 `CancelToken` API 来完成。通过将 `CancelToken` 实例注入到请求配置中,可以在需要时主动取消未完成的请求。以下是实现请求中断的具体方法和封装策略: ### 一、基于 CancelToken 的基本实现 Axios 提供了 `CancelToken` 构造函数,用于创建可取消的请求令牌。在封装的请求方法中,可以将 `cancelToken` 配置项注入到请求配置对象中,并将取消函数绑定到组件或实例上,以便在适当时机调用。 例如,在 Vue 项目中,可以在封装的请求方法中加入如下逻辑: ```javascript import axios from 'axios'; const CancelToken = axios.CancelToken; export function fetchData(url, data, that) { return axios.post(url, data, { cancelToken: new CancelToken((c) => { that.cancel = c; // 将取消函数绑定到组件实例 }) }); } ``` 在组件销毁前(如 Vue 的 `beforeDestroy` 钩子中),调用绑定的取消函数: ```javascript beforeDestroy() { if (this.cancel) { this.cancel(); // 取消尚未完成的请求 } } ``` ### 二、封装统一的中断机制 在实际项目中,可能需要统一管理多个请求的取消操作。可以通过在封装的 Axios 实例中维护一个取消队列,记录所有未完成请求的取消函数,并在适当时机批量取消。 例如,在 Axios 实例中添加请求拦截器来记录取消函数: ```javascript const service = axios.create({ baseURL: process.env.VUE_APP_API, timeout: 10000 }); const pendingRequests = []; service.interceptors.request.use(config => { config.cancelToken = new CancelToken(cancel => { pendingRequests.push(cancel); }); return config; }); // 提供一个全局取消所有请求的方法 function cancelAllRequests() { pendingRequests.forEach(cancel => cancel()); pendingRequests.length = 0; } ``` 在页面切换或组件卸载时调用 `cancelAllRequests()` 方法即可中断所有未完成的请求。 ### 三、结合接口状态管理 在一些复杂的业务场景中,可能需要根据接口状态(如是否正在加载)来决定是否中断请求。可以结合 Vuex 或 Pinia 等状态管理工具,在请求发起时更新状态,并在状态变化时触发中断逻辑。 例如,在 Vuex 中维护请求状态: ```javascript state: { isLoading: false }, mutations: { SET_LOADING(state, status) { state.isLoading = status; } } ``` 在请求封装中结合状态判断: ```javascript export function fetchData(store, url, data) { store.commit('SET_LOADING', true); return axios.post(url, data, { cancelToken: new CancelToken((c) => { if (store.state.isLoading) { c(); // 如果正在加载,立即取消请求 } }) }).finally(() => { store.commit('SET_LOADING', false); }); } ``` ### 四、封装建议与最佳实践 - **统一取消入口**:在封装中提供统一的取消入口,便于集中管理未完成的请求。 - **结合生命周期管理**:在组件或页面卸载时自动取消请求,避免内存泄漏。 - **避免重复取消**:确保取消函数仅在必要时调用,避免重复取消导致的异常。 - **结合错误处理**:对取消操作进行统一的错误处理,避免因取消请求而触发不必要的错误提示。 通过上述方法,可以在封装的 Axios 接口中灵活实现请求中断功能,提升应用的健壮性和用户体验。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值