通过调用 abortcontroller 实例的 abort() 方法可以取消正在进行的 fetch 请求,从而中断数据预加密等耗时操作。具体做法是在发起请求前创建 controller,将 signal 传入 fetch 配置中,并在需要时调用 abort(),此时请求会抛出 domexception 异常,浏览器底层会停止网络传输并释放资源。

如何正确初始化 AbortController 并绑定到 fetch
在发起请求前必须实例化 AbortController,并将其 signal 属性传递给 fetch 的第二个参数对象。这样 fetch 就能监听信号状态,一旦信号被触发,请求立即终止。这是实现取消功能的基础步骤,确保后续逻辑能捕获到取消事件。

const controller = new AbortController();
const signal = controller.signal;
fetch('/api/encrypt-data', {
method: 'POST',
body: JSON.stringify({ data: 'sensitive-info' }),
signal: signal
})
.then(res => res.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('Request cancelled');
} else {
console.error('Fetch failed:', err);
}
});
// 稍后调用以取消
controller.abort();
如何处理取消请求后的异常与状态清理
当请求被取消时,Promise 链会进入 catch 分支,抛出的错误名为 AbortError。开发者需在此处进行区分处理,避免将取消误判为网络故障。同时,若涉及前端状态管理(如 loading 状态),应在 catch 中重置 UI,防止界面卡在加载状态。这种处理方式保证了用户体验的连贯性,并符合异步编程的最佳实践。

// 模拟一个更完整的组件逻辑
let currentController = null;
function startEncryption() {
// 如果有正在进行中的请求,先取消
if (currentController) {
currentController.abort();
}
currentController = new AbortController();
const { signal } = currentController;
setLoading(true);
fetch('/api/encrypt', { signal })
.then(res => {
if (!res.ok) throw new Error('Network error');
return res.json();
})
.then(data => {
setEncryptedData(data.token);
setLoading(false);
})
.catch(err => {
setLoading(false);
if (err.name !== 'AbortError') {
showError(err.message);
}
});
}
// 用户点击取消按钮时
function handleCancel() {
startEncryption(); // 内部会自动取消上一个
}
基于 signal.aborted 属性的具体判断问题
在请求完成后或进行中,可以通过检查 controller.signal.aborted 属性来确认请求是否已被主动取消。该属性是一个布尔值,当调用 abort() 后变为 true。这在某些场景下非常有用,例如在多个并发请求中,你需要知道当前请求是因为超时、错误还是被手动取消而结束,从而执行不同的清理逻辑。结合 try-catch 和属性检查,可以实现更精细的控制流。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











