AbortController 是 JavaScript 中用于中止 fetch 请求的标准机制,通过创建控制器、传入 signal 并用 setTimeout 调用 abort() 实现超时控制;需每次新建控制器,现代浏览器支持,IE 不支持。

在 JavaScript 中,AbortController 是标准的中止信号机制,配合 fetch 可以优雅地实现请求超时中断。关键在于:创建控制器、传入 signal、用 setTimeout 主动调用 abort()。
1. 基础用法:手动触发 abort 实现超时
最常用的方式是设置一个定时器,在指定毫秒后调用 controller.abort()。一旦 abort 被调用,关联的 fetch 请求会立即 reject 并抛出 AbortError。
示例:
const controller = new AbortController();
const signal = controller.signal;
// 5 秒后自动中止请求
setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('/api/data', { signal });
const data = await response.json();
console.log(data);
} catch (err) {
if (err.name === 'AbortError') {
console.log('请求已超时,被中止');
} else {
console.error('其他错误:', err);
}
}
2. 封装成可复用的超时 fetch 函数
避免每次重复写 setTimeout 和 try/catch,可以封装一个带超时控制的 fetch 工具函数:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
说明:
- 接收 URL、配置对象(可选)、超时毫秒数(默认 10000)
- 内部自动创建
AbortController并绑定超时逻辑 - 返回 Promise,正常 resolve 或 reject
AbortError
function timeoutFetch(url, options = {}, timeout = 10000) {
const controller = new AbortController();
const signal = controller.signal;
const timeoutId = setTimeout(() => controller.abort(), timeout);
return fetch(url, {
...options,
signal
}).finally(() => clearTimeout(timeoutId));
}
使用:
timeoutFetch('/api/user', { method: 'POST' }, 3000)
.then(res => res.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('3 秒内未响应,请求已取消');
}
});
3. 注意事项与常见问题
实际使用中需留意以下几点:
-
signal 只能使用一次:abort 后不可重用,每次请求都应新建
AbortController - 浏览器兼容性:现代浏览器均支持,但 IE 完全不支持(需 polyfill 或降级处理)
- fetch 拒绝时机:abort 不会终止底层网络连接,但会立即让 fetch Promise reject,后续逻辑不再执行
-
与 Axios 区别:Axios 的
timeout选项是自身实现的封装,并非基于 AbortController;原生 fetch 必须靠 signal
4. 结合 Promise.race 实现更紧凑写法(进阶)
如果偏好函数式风格,可用 Promise.race 显式竞争超时和请求结果:
function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const fetchPromise = fetch(url, { signal: controller.signal });
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => {
controller.abort();
reject(new Error('Request timed out'));
}, timeout);
});
return Promise.race([fetchPromise, timeoutPromise]);
}
注意:这种方式中,timeoutPromise 的 reject 信息不如检查 AbortError 精准,推荐优先用第一种方式。

















