当前位置: 首页 > news >正文

Vue 项目中使用 AbortController:解决请求取消、超时与内存泄漏问题

文章目录

    • 一、基础概念
    • 二、实用特性与 Vue 项目示例
      • 1. 中止单个请求(搜索输入场景)
      • 2. 一个信号控制多个请求(页面卸载时统一中止)
      • 3. 组件卸载时中止请求(避免内存泄漏)
      • 4. 超时自动取消请求
      • 5. 封装请求工具,便于全局使用
    • 三、总结

在平时项目开发中,经常遇到这些问题:

  • 用户快速切换页面:旧请求还没返回,新页面的请求已经发出,导致页面闪烁或数据错乱。
  • 搜索框实时输入:用户频繁输入关键词,旧请求结果覆盖了最新结果。
  • 组件卸载时仍在更新状态:报错 Cannot update state on an unmounted component
  • 长耗时请求:用户想手动取消,或需要设置超时时间,避免页面卡死。
  • 批量请求管理困难:进入一个页面时要请求多个接口,但离开页面时要统一取消。

这些场景如果不处理好,不仅影响性能,还会带来糟糕的用户体验。
幸运的是,AbortController 提供了优雅的解决方案。


一、基础概念

  • AbortController:通过 new AbortController() 创建控制器。
  • signal:使用 controller.signal 传递给需要中止的请求。
  • abort():调用后,所有绑定该信号的请求都会立即中止。

二、实用特性与 Vue 项目示例

1. 中止单个请求(搜索输入场景)

👉 应用场景:防止旧搜索结果覆盖新结果。

<script setup>
import { ref } from "vue";let controller = null;
const results = ref([]);async function search(keyword) {// 中止上一个请求if (controller) controller.abort();controller = new AbortController();const { signal } = controller;try {const res = await fetch(`/api/search?q=${keyword}`, { signal });results.value = await res.json();} catch (err) {if (err.name === "AbortError") {console.log("请求被中止:", keyword);}}
}
</script><template><div><input type="text" @input="e => search(e.target.value)" placeholder="搜索..." /><ul><li v-for="item in results" :key="item.id">{{ item.name }}</li></ul></div>
</template>

2. 一个信号控制多个请求(页面卸载时统一中止)

👉 应用场景:进入新页面时,老页面的所有请求都自动中止。

<script setup>
import { onBeforeUnmount, ref } from "vue";const user = ref(null);
const messages = ref([]);
const notifications = ref([]);
const controller = new AbortController();
const { signal } = controller;async function loadData() {try {const [u, m, n] = await Promise.all([fetch("/api/user", { signal }),fetch("/api/messages", { signal }),fetch("/api/notifications", { signal })]);user.value = await u.json();messages.value = await m.json();notifications.value = await n.json();} catch (err) {if (err.name === "AbortError") {console.log("所有请求被中止");}}
}loadData();// 页面卸载时统一中止
onBeforeUnmount(() => controller.abort());
</script><template><div><h2>{{ user?.name }}</h2><p>消息数量: {{ messages.length }}</p><p>通知数量: {{ notifications.length }}</p></div>
</template>

3. 组件卸载时中止请求(避免内存泄漏)

👉 应用场景:Vue 组件卸载时防止“状态更新到已销毁的组件”报错。

<script setup>
import { onBeforeUnmount, ref } from "vue";const user = ref(null);
const controller = new AbortController();fetch("/api/user", { signal: controller.signal }).then(res => res.json()).then(data => (user.value = data)).catch(err => {if (err.name === "AbortError") {console.log("请求被中止:组件卸载");}});// 卸载时中止
onBeforeUnmount(() => controller.abort());
</script><template><div><h2 v-if="user">{{ user.name }}</h2><p v-else>加载中...</p></div>
</template>

4. 超时自动取消请求

👉 应用场景:请求超时自动取消,避免长时间无响应。

<script setup>
async function fetchWithTimeout(url, timeout = 5000) {const controller = new AbortController();const { signal } = controller;const timer = setTimeout(() => controller.abort(), timeout);try {const res = await fetch(url, { signal });return await res.json();} finally {clearTimeout(timer);}
}fetchWithTimeout("/api/slow", 3000).then(data => console.log("成功:", data)).catch(err => {if (err.name === "AbortError") {console.log("请求超时,已中止");}});
</script>

5. 封装请求工具,便于全局使用

// utils/http.js
export class HttpClient {constructor() {this.controller = null;}request(url, options = {}) {if (this.controller) this.controller.abort();this.controller = new AbortController();return fetch(url, { ...options, signal: this.controller.signal });}cancel() {if (this.controller) this.controller.abort();}
}
/// Vue中
<script setup>
import { HttpClient } from "@/utils/http";const client = new HttpClient();async function loadData() {try {const res = await client.request("/api/data");console.log(await res.json());} catch (err) {if (err.name === "AbortError") {console.log("请求被取消");}}
}// 手动取消
setTimeout(() => client.cancel(), 1000);
</script>

三、总结

在项目中,AbortController 主要能解决以下问题:

  1. 搜索输入时中止旧请求 → 保证数据正确。
  2. 统一中止多个请求 → 页面切换时清理资源。
  3. 组件卸载时中止请求 → 避免内存泄漏与报错。
  4. 超时自动取消 → 提升用户体验。
  5. 工具类封装 → 增强代码复用性和可维护性。

一句话记忆:
AbortController 就是请求的“刹车器”,能在项目中随时中止请求,保证性能与体验。

http://www.dtcms.com/a/389842.html

相关文章:

  • 设置管家婆服务器开机自动启动
  • ubuntu20 安装 ros2 foxy
  • 二分查找(二分查找算法)
  • 贪心算法应用:超图匹配问题详解
  • Hadoop3.3.5搭建指南(双NN版本)
  • 如何正确写Controller?参数校验、异常处理
  • 线性代数:LU与Cholesky分解
  • 饮用水在线监测设备:实时、精准地捕捉水体中的关键参数,为供水安全提供全方位保障
  • 【环境搭建】Conda安装教程
  • Java与机器学习的结合:库与应用!
  • DHCP基本原理及实验(ENSP配置)
  • 高系分十一:软件需求工程
  • MCP Server Chart AntV 项目解析
  • 2025药物市场调研分析案例(模板资源分享)
  • 飞网出口网关:安全便捷地访问受限资源
  • 大模型训练的三大显存优化策略
  • 动态加载js链接、异步传参加载组件、有趣打印
  • 【Python】Python异常、模块与包
  • 第三方网站系统测试:【基于Pytest的自动化测试框架的测试】
  • 每个 SIwave 求解器的正确激励
  • 给 C++ Protobuf“装上 Abseil”版本确认、Bazel/CMake 实战与避坑
  • Java 大视界 -- Java 大数据在智能物流运输车辆智能调度与路径优化中的技术实现
  • 电脑中的32位和64位
  • 如何免费使用AWS服务器?AWS Free Tier免费套餐申请与避坑指南
  • QML界面调用C++层阻塞函数,如何不卡界面
  • JVM GC 调优:GC 问题发现工具,五大 GC 异常模式,四大调优方案与案例实战
  • Excel处理控件Aspose.Cells教程:如何使用Python在Excel中创建下拉列表
  • React 18.2中使用Redux 5.0.1
  • 程序开发的基本规律
  • Day26_【深度学习(6)_神经网络NN(1.1)激活函数_softmax详解篇】