vue 中接口多次重复调用

代码里一个接口莫名多次调用,经排查发现是使用bus时未调用off方法注销对应事件所致,这属于前端开发中易遇到的问题。

在代码中发现一个接口总是莫名奇妙的调用多次,一直找不到原因,后来发现是在使用bus的过程中没用调用off方法将对应的事件注销导致的

### Vue 接口重复请求的原因分析 在开发过程中遇到接口被重复调用的情况,通常有几种常见原因: - **生命周期钩子函数中的副作用**:如果网络请求放置于 `mounted` 或其他生命周期钩子内,并且这些钩子由于某些条件而被执行多次,则可能导致不必要的额外请求[^4]。 - **路由导航守卫的影响**:当使用 Vue Router 时,特定情况下(如快速切换相同路径),可能会导致组件重新渲染进而触发新的 API 调用[^1]。 - **未正确管理并发请求**:对于频繁发生的交互操作(例如点击按钮发送表单数据),如果没有适当机制来防止短时间内多次提交相同的请求,也会造成重复现象[^3]。 ### 解决方案概述 针对上述提到的各种可能性,可以采取如下措施来预防或修复该类问题: #### 方法一:优化生命周期内的异步任务执行 为了避免因为生命周期反复触发展开过多 HTTP 请求,在发起任何远程调用之前应该先确认当前实例的状态是否允许这样做。可以通过设置标志位或者利用防抖/节流技术控制频率。 ```javascript data() { return { isFetching: false, }; }, methods: { fetchData() { if (!this.isFetching) { // 只有当没有正在进行的数据获取过程才继续 this.isFetching = true; axios.get('/api/data') .then(response => { console.log('Data fetched:', response.data); this.isFetching = false; // 完成后重置状态以便下次正常工作 }) .catch(error => { console.error('Error fetching data', error); this.isFetching = false; // 出错也要记得恢复标记 }); } }, } ``` #### 方法二:采用 Axios 的取消令牌功能 为了更优雅地处理这种情况,还可以借助 Axios 提供的取消令牌特性,确保每次新请求到来前能够安全地中止旧的任务而不影响用户体验。 ```javascript import axios from 'axios'; // 创建一个 CancelToken 实例用于存储取消信号源对象 let cancelSource; const fetchWithCancelSupport = () => { // 如果存在上一次遗留下来的取消器则立即终止它 if (cancelSource) { cancelSource.cancel(); } // 初始化一个新的取消器并保存起来方便后续访问 cancelSource = axios.CancelToken.source(); return axios({ url: '/api/resource', method: 'GET', cancelToken: cancelSource.token, }).then((response) => { /* ... */ }).catch(thrown => { if (axios.isCancel(thrown)) { console.log('Request canceled'); } else { throw thrown; } }); }; ``` #### 方法三:引入全局拦截器统一配置 除了局部调整外,也可以在整个应用程序级别定义通用的行为模式,比如通过自定义 Axios 拦截器实现自动化的请求去重逻辑。 ```javascript axios.interceptors.request.use(config => { const key = `${config.method}-${config.url}`; if (pendingRequests.has(key)) { pendingRequests.get(key).cancel(); // 清除已存在的同名请求 // 移除老版本记录 pendingRequests.delete(key); } config.cancelToken = new axios.CancelToken(canceler => { pendingRequests.set(key, { cancel: canceler }); // 添加最新创建者至集合中跟踪 }); return config; }, error => Promise.reject(error)); // 别忘了清理不再需要的对象引用以防内存泄漏 axios.interceptors.response.use( response => { const key = `${response.config.method}-${response.config.url}`; pendingRequests.delete(key); // 成功响应之后移除对应项 return response; }, error => { const key = `${error.config?.method}-${error.config?.url}`; pendingRequests.delete(key); // 即使发生错误也需要做同样的事情 return Promise.reject(error); } ); // 使用 WeakMap 来保持弱引用关系从而避免潜在GC障碍 const pendingRequests = new WeakMap(); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值