JavaScript中fetch超时需用AbortController配合setTimeout实现:先创建controller并传signal,再设定时器调abort(),最后fetch;需捕获AbortError区分超时与其他错误。

在 JavaScript 中,fetch 本身不支持超时参数,但可以通过 AbortController 主动中止请求,再配合 setTimeout 实现超时控制。
创建 AbortController 并传入 signal
先实例化 AbortController,把它的 signal 对象作为选项传给 fetch。这样当调用 controller.abort() 时,正在进行的 fetch 请求就会被终止,并抛出 AbortError。
- 确保每次请求都新建一个
AbortController,避免多个请求共用 signal 导致误中断 -
signal是只读属性,不可替换;中止后无法重用该 controller
用 setTimeout 触发 abort
在发起 fetch 前设置定时器,超时后调用 controller.abort()。注意:必须在 fetch 调用之后、await 之前设置定时器,否则可能因异步执行顺序导致 abort 未生效。
- 推荐写法:先 new controller,再设 timeout,再调 fetch —— 三步紧邻,不穿插其他异步操作
- 超时时间建议设为毫秒(如
5000表示 5 秒),和后端预期响应时间匹配 - 如果 fetch 已完成,再调
abort()不会报错,是安全操作
捕获 AbortError 并区分错误类型
fetch 被中止时会拒绝 Promise,且 error.name === 'AbortError'。需要显式判断这个类型,避免和网络错误、404 等混淆。
立即学习“Java免费学习笔记(深入)”;
- 不要只靠
catch捕获所有错误就认为是超时 —— 必须检查error.name - 可以封装工具函数统一处理,例如返回
{ ok: false, type: 'timeout' } - 浏览器兼容性良好(Chrome 66+、Firefox 57+、Safari 12.1+),无需 polyfill
完整示例代码
以下是一个带超时的 fetch 封装函数:
async function fetchWithTimeout(url, options = {}, timeout = 5000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(id);
return response;
} catch (err) {
clearTimeout(id);
if (err.name === 'AbortError') {
throw new Error('Request timed out');
}
throw err;
}
}
// 使用
fetchWithTimeout('/api/data', { method: 'POST' }, 3000)
.then(res => res.json())
.catch(err => console.error(err.message)); // "Request timed out"


















