JS-AbortController:优雅中止请求操作

0 阅读2分钟

前言

在前端开发中,我们经常遇到需要中途撤回请求的情况(例如:搜索框快速输入、大型文件上传取消、或是 AI 聊天流的即时中断)。传统的 Promise 一旦启动就无法在外部“叫停”,而 AbortController 的出现,完美填补了这一空白。

一、 核心概念与原理

AbortController 是 JavaScript 内置的信号控制对象,它是实现异步操作可控制、可中止的核心。

1. 关键组成部分

  • controller.signal:一个 AbortSignal 对象实例。它充当“监听器”,将其传递给异步操作后,该操作会持续观察信号状态。

  • controller.abort() :触发中止的方法。调用后,signal 上的 abort 事件会被触发,同时将 signal.aborted 设为 true


二、 基础使用模式

1. 实现步骤

  1. 使用 new AbortController() 生成实例。
  2. 将实例中的 signal 属性传递给需要支持中止的异步 API(如 fetch)。
  3. 在合适的时机调用 controller.abort() 即可主动终止。

2. 代码示例

// 1. 创建 AbortController 实例
const controller = new AbortController();
const { signal } = controller;

// 2. 发起请求并绑定信号
fetch("/api/data", { signal })
  .then((response) => response.json())
  .then((data) => console.log("请求成功:", data))
  .catch((err) => {
    // 3. 捕获中止错误
    if (err.name === "AbortError") {
      console.log("主动取消:请求被成功截断");
    } else {
      console.error("请求失败:", err);
    }
  });

// 2 秒后主动取消请求
setTimeout(() => {
  controller.abort(); 
}, 2000);

三、 进阶技巧与场景

1. 批量取消请求

如果想同时取消多个相关的请求,可以给这些请求共享同一个 signal。当调用 abort() 时,所有关联的任务都会收到中止信号。

2. 示例

// 使用同一个 AbortController 取消多个请求
const controller = new AbortController();

// 请求1
const request1 = fetch('url1', {
  signal: controller.signal
});

// 请求2
const request2 = fetch('url2', {
  signal: controller.signal
});

// 请求3
const request3 = fetch('url3', {
  signal: controller.signal
});

// 同时取消所有请求
document.getElementById('cancelBtn').addEventListener('click', () => {
  controller.abort();
  console.log('所有请求已取消');
});

// 等待所有请求
Promise.all([request1, request2, request3])
  .then(responses => Promise.all(responses.map(r => r.json())))
  .then(data => console.log('所有数据:', data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('请求被取消');
    }
  });

3. 注意事项

  • 兼容性:并非所有 API 都原生支持。目前 fetchAxios (v0.22+) 模块已提供支持。
  • 幂等性abort() 方法只能生效一次。多次调用虽然不会报错,但只有第一次调用会触发中止逻辑。

四、 总结对比

特性传统 Promise带有 AbortController 的 Promise
可控性开启后无法干预可随时通过 abort() 中止
异常处理只有成功/失败增加 AbortError 类型,方便区分主动取消与网络异常
应用场景简单的数据获取复杂交互、流式输出、性能调优