避免重复请求,请求防抖
const res: any = await getBaseData({
...queryParams.value
}, {
signal: abortController.value.signal // 传递取消信号
});
这段代码使用了 Axios 的请求取消(Request Cancellation) 机制。
核心含义
signal: abortController.value.signal 的作用是将当前的 HTTP 请求与一个 AbortController 控制器绑定。当这个控制器被调用 abort() 方法时,正在进行的网络请求会被立即中断(取消),从而节省带宽、减少服务器压力,并避免旧请求的数据覆盖新请求的数据(竞态条件)。
详细解析
1. AbortController 是什么?
AbortController 是一个原生 JavaScript API,用于控制一个或多个 DOM 请求(如 fetch 或 axios)。
- 创建:
new AbortController()创建一个控制器实例。 - 信号:
controller.signal是一个对象,包含请求的状态。 - 取消:
controller.abort()会触发信号,通知所有监听该信号的请求“停止”。
2. 在代码中是如何工作的?
请看完整逻辑:
const getList = async () => {
// 1. 【关键步骤】如果之前有一个未完成的请求,先强制取消它
if (abortController.value) {
abortController.value.abort();
}
// 2. 【关键步骤】创建一个新的控制器,用于管理本次请求
abortController.value = new AbortController();
try {
loading.value = true;
// 3. 【关键步骤】将新控制器的 signal 传递给 axios
const res: any = await getBaseData({
...queryParams.value
}, {
signal: abortController.value.signal // <--- 这里绑定信号
});
comPartsNoticeList.value = res?.data || [];
} catch (error: any) {
// 4. 【关键步骤】捕获取消错误
if (error.name === 'AbortError' || error.message?.includes('canceled')) {
console.log('请求已取消,忽略响应');
return; // 如果是被取消的,直接返回,不处理数据
}
// 处理其他真实错误...
} finally {
loading.value = false;
}
};
3. 为什么要这么做?(应用场景)
在定时刷新场景中,这非常重要:
-
防止竞态条件(Race Condition):
假设用户快速点击了“手动刷新”按钮两次,或者定时器触发时上一个请求还没回来。- 没有取消机制:第一个请求可能比第二个请求晚返回。结果就是:界面先显示第二次请求的数据,然后突然跳变回第一次请求的旧数据。这会导致数据不一致。
- 有取消机制:第二次点击时,代码执行
abortController.value.abort(),第一个请求直接被杀死。只有第二个请求会成功返回并更新界面。保证界面永远显示最新的请求结果。
-
节省资源:
如果用户频繁改变请求参数,或者快速刷新,旧的、不再需要的请求会被立即终止,不再占用浏览器和服务器的资源。 -
组件卸载时清理:
在onUnmounted中:onUnmounted(() => { stopTimer(); if (abortController.value) { abortController.value.abort(); // 组件销毁时,如果还有请求在跑,立即取消 abortController.value = null; } });这防止了组件销毁后,异步请求回来尝试更新已销毁组件的状态(这通常会导致 Vue 警告或内存泄漏)。
总结
| 代码部分 | 作用 |
|---|---|
new AbortController() |
创建一个“遥控器”,用于控制本次请求。 |
signal: ... |
把“遥控器”的信号接收器交给 Axios。Axios 会监听这个信号。 |
abortController.value.abort() |
按下“遥控器”的取消键。Axios 收到信号后,立即中断网络请求,抛出 AbortError。 |
catch (error) 中的判断 |
区分是“正常网络错误”还是“我主动取消的错误”。如果是主动取消,则静默忽略。 |
这是一种最佳实践,特别是在高频刷新、搜索防抖或单页应用(SPA)路由切换的场景中。

浙公网安备 33010602011771号