fetch 用 abortsignal 实现多个关联请求一键取消,核心是共享同一 abortcontroller 的 signal;调用 controller.abort() 即终止所有绑定该 signal 的请求,且 signal 一次性使用,不可复用。

Fetch 用 AbortSignal 实现多个关联请求的一键取消,核心是让多个 fetch 共享同一个 AbortController 实例的 signal。只要调用一次 controller.abort(),所有绑定该 signal 的请求都会立即终止。
创建并共享同一个 AbortController
多个请求要能被“一键”取消,前提是它们使用同一个 signal。不能每个请求都新建一个 AbortController,否则调用 abort 只会影响其中一个。
- 在发起请求前,统一创建一个
AbortController - 把它的
signal分别传给每个fetch的options.signal - 后续只需调用这一个 controller 的
abort()即可批量取消
实际写法示例(多个并行请求)
比如搜索页同时请求用户信息、历史记录和推荐列表:
const controller = new AbortController();
const { signal } = controller;
// 三个请求共用同一个 signal
const userPromise = fetch('/api/user', { signal });
const historyPromise = fetch('/api/history', { signal });
const recPromise = fetch('/api/recommend', { signal });
// 用 Promise.all 并行发起,任意一个 reject(包括 abort)都会触发 catch
Promise.all([userPromise, historyPromise, recPromise])
.then(responses => Promise.all(responses.map(r => r.json())))
.then(data => console.log('全部成功', data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求已被取消');
} else {
console.error('其他错误', err);
}
});
// 点击取消按钮时
document.getElementById('cancel-btn').addEventListener('click', () => {
controller.abort(); // 一句话取消全部
});
注意 signal 的生命周期和复用限制
AbortSignal 是一次性使用的:一旦 abort,该 signal 就进入已终止状态,不能再用于新请求。
- 如果需要重新发起请求,必须新建
AbortController - 不要把已 abort 的 signal 再传给新的
fetch,会直接抛AbortError - 可以封装一个函数,在每次请求前生成新 controller,但“一键取消”需保留对 controller 的引用
进阶:封装可取消的请求组合工具
为简化管理,可封装一个返回 { promise, abort } 的函数:
function createBatchRequest(urls) {
const controller = new AbortController();
const promises = urls.map(url =>
fetch(url, { signal: controller.signal })
.then(r => r.json())
);
return {
promise: Promise.all(promises),
abort: () => controller.abort()
};
}
// 使用
const batch = createBatchRequest([
'/api/profile',
'/api/notifications',
'/api/feed'
]);
batch.promise.then(data => console.log(data));
// 需要时
batch.abort(); // 一键取消全部
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











