Promise 本身不可取消,因其状态一旦开始便只能单向变为 fulfilled 或 rejected;所谓“取消”实为通过 AbortController 向 fetch 等原生支持 signal 的 API 发送中止信号,使其立即 reject AbortError,并由开发者主动忽略后续逻辑。

Promise 本身不支持取消,但结合 AbortController 可以实现“可中断”的异步请求逻辑——关键不是让 Promise 自身取消,而是让底层操作(如 fetch)响应中止信号,并让 Promise 尽快 reject 或忽略后续结果。
为什么 Promise 不能原生取消?
Promise 一旦创建并开始执行(例如进入 fetch 或 setTimeout),其状态只能从 pending → fulfilled 或 rejected,且不可逆、不可中途终止。所谓“取消”,实际是:提前通知正在运行的异步任务停止工作,并避免它再调用 resolve 或 reject。
AbortController 如何与 fetch 配合中断请求
fetch 是目前唯一原生支持 AbortSignal 的浏览器 API。调用 abort() 后,fetch 会立即 reject 一个 DOMException(name: "AbortError"),你可以捕获它来区分正常失败和主动取消:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/data', { signal })
.then(res => res.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求已被取消');
} else {
console.error('请求出错:', err);
}
});
// 3 秒后取消(模拟用户点击“取消”)
setTimeout(() => controller.abort(), 3000);
封装成可取消的 Promise 工厂函数
为复用逻辑,可写一个返回 { promise, abort } 的函数,把控制权暴露给调用方:
立即学习“Java免费学习笔记(深入)”;
function cancellableFetch(url, options = {}) {
const controller = new AbortController();
const signal = controller.signal;
const promise = fetch(url, { ...options, signal })
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
});
return {
promise: promise.catch(err => {
if (err.name === 'AbortError') throw new Error('FETCH_CANCELLED');
throw err;
}),
abort: () => controller.abort()
};
}
// 使用示例
const { promise, abort } = cancellableFetch('/api/user/123');
promise.then(console.log).catch(console.error);
// 需要时调用
abort();
注意:其他异步操作需手动响应 signal
像 setTimeout、WebSocket 或自定义异步逻辑不会自动监听 signal,必须手动检查 signal.aborted 并提前退出:
- 定期轮询时,在每次迭代前加
if (signal.aborted) return; - 使用
signal.addEventListener('abort', handler)做清理(如关闭 socket、清除定时器) - 避免在 abort 后继续 resolve/reject —— 可用标志位或
signal.throwIfAborted()(现代环境支持)

















