Vue3中AbortController取消请求的用法详解

在 Vue3 中,AbortController 用于取消 fetch 请求,避免组件卸载后仍执行异步操作导致的潜在问题(如内存泄漏或更新已销毁组件的状态)。以下是详细用法和最佳实践:


一、基本用法

  1. 创建 AbortController 实例

    在组件 setup() 中创建实例,并通过 signal 关联请求:

    javascript

    复制代码
    import { onUnmounted } from 'vue';
    
    export default {
      setup() {
        const controller = new AbortController();
        const signal = controller.signal;
    
        // 发送请求时传递 signal
        fetch('/api/data', { signal })
          .then(response => response.json())
          .catch(err => {
            if (err.name === 'AbortError') {
              console.log('请求已取消');
            } else {
              console.error('请求失败:', err);
            }
          });
    
        // 组件卸载时取消请求
        onUnmounted(() => controller.abort());
    
        return {};
      },
    };

二、结合异步操作

在异步函数中结合 AbortController

javascript

复制代码
import { onUnmounted } from 'vue';

export default {
  setup() {
    const controller = new AbortController();
    const fetchData = async () => {
      try {
        const response = await fetch('/api/data', { signal: controller.signal });
        const data = await response.json();
        // 处理数据
      } catch (err) {
        if (err.name === 'AbortError') {
          console.log('请求已取消');
        } else {
          console.error('请求失败:', err);
        }
      }
    };

    fetchData();

    onUnmounted(() => controller.abort());
  },
};

三、管理多个请求

单个 AbortController 可取消多个请求:

javascript

复制代码
const controller = new AbortController();

// 请求1
fetch('/api/data1', { signal: controller.signal });

// 请求2
fetch('/api/data2', { signal: controller.signal });

// 取消所有请求
controller.abort();

四、与 Axios 结合使用

如果使用 Axios,可通过 CancelToken(旧版)或 AbortController(Axios >= 0.22.0)取消请求:

javascript

复制代码
import axios from 'axios';

const controller = new AbortController();

axios.get('/api/data', {
  signal: controller.signal,
})
  .then(response => { /* ... */ })
  .catch(err => {
    if (axios.isCancel(err)) {
      console.log('请求已取消');
    }
  });

// 取消请求
controller.abort();

五、注意事项

  1. 兼容性
    AbortController 在现代浏览器中支持良好,但需考虑旧版浏览器兼容性(可通过 polyfill 解决)。

  2. 错误处理

    捕获 AbortError 避免未处理的 Promise 拒绝。

  3. 复用 Controller

    每次新请求前创建新的 AbortController,避免重复使用已取消的实例。


六、最佳实践

  • 在组件卸载时取消请求 :在 onUnmounted 生命周期钩子中调用 abort()

  • 封装可复用的逻辑 :将取消逻辑封装到自定义 Hook 中(如 useFetch)。

  • 避免内存泄漏:确保所有未完成的请求在组件销毁时被取消。


通过合理使用 AbortController,可以有效管理 Vue3 中的异步操作,提升应用性能和稳定性。

TypeScript 复制代码
// 获取配置项内容
export const selectOptionsService = (optionItemId: string, signal?: AbortSignal) => {
  return request.get("selectOptions/SystemOptions", {
    params: {
      optionItemId: optionItemId
    },
    // 设置 signal 信号属性,后续就可以通过 abort 取消请求
    signal: signal
  });
};
TypeScript 复制代码
......

// 创建 AbortController 用于取消请求
const controller = new AbortController();

      // 并发加载多个选项
      const [wspjTypeResult, cyTypeResult, payTypeResult] = await Promise.allSettled([
        // 设置信号 AbortSignal,关联请求,以便能取消请求
        usePostServiceHook(selectOptionsService, ["lbWSPJType", controller.signal]),
        usePostServiceHook(selectOptionsService, ["cyType", controller.signal]),
        usePostServiceHook(selectOptionsService, ["lbFAX", controller.signal])
      ]);

onUnmounted(() => {
  // 取消请求
  controller.abort();
});
......
相关推荐
恋猫de小郭6 分钟前
Flutter 官方 LLM 动态 UI 库 flutter_genui 发布,让 App UI 自己生成 UI
android·前端·flutter
薄雾晚晴7 分钟前
Rspack 实战:用 image-minimizer-webpack-plugin 做图片压缩,优化打包体积
javascript·vue.js
niuhuahua8 分钟前
大模型流式聊天,实时对话,快捷问题选项
vue.js
JIngJaneIL16 分钟前
汽车租赁|基于Java+vue的汽车租赁系统(源码+数据库+文档)
java·vue.js·spring boot·汽车·论文·毕设·汽车租赁系统
kymjs张涛29 分钟前
零一开源|前沿技术周刊 #15
前端·javascript·面试
Artea30 分钟前
聊聊 Vue3 的泛型
vue.js
BYSJMG30 分钟前
计算机毕业设计选题:基于Spark+Hadoop的健康饮食营养数据分析系统【源码+文档+调试】
大数据·vue.js·hadoop·分布式·spark·django·课程设计
reacx30 分钟前
# 第三章:状态管理架构设计 - 从 Zustand 到 React Query 的完整实践
前端
古夕32 分钟前
Vue3 + vue-query 的重复请求问题解决记录
前端·javascript·vue.js
不知名程序员第二部32 分钟前
前端-业务-架构
前端·javascript·代码规范