abortcontroller 和 abortsignal 是 javascript 中用于取消异步操作(如 fetch)的标准机制。通过新建 abortcontroller 实例并传入 signal,可手动调用 abort() 中止请求,适用于取消按钮、组件卸载、超时控制等场景;多次 abort 安全但 signal 不可重用;配合 settimeout 可实现超时自动取消;在 react 等框架中需在清理函数中调用 abort 以避免内存泄漏。

在 JavaScript 中,AbortController 和 AbortSignal 是标准的取消异步操作(如 fetch)的机制。它们提供了一种干净、原生的方式中断正在进行的请求,避免内存泄漏或无效回调执行。
创建 AbortController 并传入 signal
每次需要可取消的 fetch 时,先新建一个 AbortController 实例,然后把它的 signal 属性作为 fetch 的选项传入:
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求已被取消');
} else {
console.error('请求失败:', err);
}
});
手动触发取消(abort)
调用 controller.abort() 即可立即中止关联的 fetch 请求。此时 fetch 的 Promise 会以 AbortError 拒绝:
- 通常用于用户点击“取消”按钮、组件卸载(如 React 中的
useEffect清理函数)、超时控制等场景 - 多次调用
abort()是安全的,重复调用无副作用 - 一旦 abort,该
signal不可重用,需新建AbortController发起新请求
配合超时自动取消
可以结合 setTimeout 实现请求超时控制:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒超时
fetch('/api/data', { signal: controller.signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求超时或被取消');
} else {
console.error('请求出错:', err);
}
})
.finally(() => clearTimeout(timeoutId));
在现代框架中注意清理(如 React)
在组件卸载时忘记 abort,可能导致状态更新到已销毁的组件上(如 setState on unmounted component 警告):
- React 函数组件中,应在
useEffect的清理函数里调用controller.abort() - 确保每个请求使用独立的
AbortController,不要复用 signal 到多个 fetch - 如果使用自定义 Hook 封装 fetch,应暴露 abort 方法或自动处理清理











