promise本身无超时机制,需用promise.race配合定时reject的promise实现:创建延迟拒绝的promise与原promise竞争,先完成者决定结果;原promise不会自动取消,真正中止需结合abortcontroller。

Promise 本身不内置超时机制,但可以通过 Promise.race() 配合一个延迟触发的拒绝 Promise 来实现超时自动拒绝。
用 Promise.race 实现超时控制
核心思路是:把目标 Promise 和一个「定时拒绝」的 Promise 一起传入 Promise.race,谁先完成(fulfilled 或 rejected),就以谁的结果为准。如果目标操作耗时超过设定时间,定时拒绝就会胜出,整个 Promise 就被自动拒绝。
- 创建一个在指定毫秒后调用
reject的 Promise,例如:new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), ms)) - 用
Promise.race([originalPromise, timeoutPromise])包裹原操作 - 注意:原 Promise 不会自动取消,只是结果被忽略;如需真正中止(比如取消 fetch 请求),需配合 AbortController 等机制
封装成可复用的 timeout 函数
把逻辑抽成函数,方便多次使用:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
function timeout(promise, ms) {
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('Request timed out')), ms);
});
return Promise.race([promise, timeoutPromise]);
}
用法示例:
timeout(fetch('/api/data'), 5000)
.then(res => res.json())
.catch(err => {
if (err.message === 'Request timed out') {
console.log('请求超时');
} else {
console.log('其他错误', err);
}
});
处理常见陷阱
实际使用中容易忽略几个细节:
-
错误类型统一性:超时返回的是
Error实例,和业务错误类型一致,便于统一捕获 - 避免重复 resolve/reject:原 Promise 即使后续完成,也不会影响已决结果,无需额外防护
-
精度与兼容性:
setTimeout的最小延迟约 4ms,对极高精度场景需另作处理;所有现代浏览器都支持Promise.race
进阶:支持自定义超时错误或取消信号
可以增强 timeout 函数,支持传入错误构造器或 AbortSignal:
- 允许传入自定义错误类或消息,提升可读性
- 结合
AbortController在超时后主动中断 fetch、XMLHttpRequest 等可取消操作 - 例如 fetch 场景下,超时不仅拒绝 Promise,还调用
abortController.abort()停止网络请求
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










