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();
});
......
相关推荐
agenIT39 分钟前
micro-app前端微服务原理解析
前端·微服务·架构
小宁爱Python1 小时前
深入理解CSS显示模式与盒子模型
前端·css
淘源码d1 小时前
一套SaaS ERP管理系统源码,支持项目二开商用,SpringBoot+Vue+ElementUI+UniAPP
vue.js·spring boot·elementui·erp·erp系统·erp源码
只可远观1 小时前
Git 忽略文件配置 .gitignore
android·前端·git
向上的车轮2 小时前
JavaScript的3D库有哪些?
开发语言·javascript·3d
我是大头鸟2 小时前
SpringMVC 通过ajax 前后端数据交互
前端·javascript·ajax
北观止2 小时前
批量删除OpenStack实例
linux·前端·chrome·openstack
爱笑的眼睛112 小时前
React Native 入门 jsx tsx 基础语法
javascript·react native·react.js
heroboyluck4 小时前
rust 全栈应用框架dioxus
前端·rust·dioxus