abortcontroller可取消图片预加载的核心是fetch+createobjecturl:用signal中断fetch获取blob,再转为image.src;直接设img.src不可取消,因无abort机制。

用 AbortController 取消图片异步预加载,核心是把 fetch() 请求和 Image 对象的加载过程统一到同一个信号(signal)下。但要注意:Image 本身不支持 AbortSignal,所以不能直接中止 img.src 的加载;真正可取消的是 fetch() 获取图片资源的过程,之后再用 Blob 或 URL.createObjectURL 渲染到 Image。
✅ 推荐方式:fetch + createObjectURL + signal
这是最可控、真正能中断网络请求的做法:
- 用
fetch(url, { signal })获取图片二进制数据,支持 abort - 成功后转成
Blob,再用URL.createObjectURL(blob)生成本地 URL - 赋给
new Image().src,完成渲染 - 若中途调用
controller.abort(),fetch立即 reject,后续逻辑不会执行
示例代码:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
function preloadImage(url) {
const controller = new AbortController();
return {
promise: fetch(url, { signal: controller.signal })
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.blob();
})
.then(blob => {
const img = new Image();
img.src = URL.createObjectURL(blob);
// 可选:加载完成后自动释放 blob URL
img.onload = () => URL.revokeObjectURL(img.src);
return img;
}),
abort: () => controller.abort()
};
}
// 使用
const loader = preloadImage('/photo.jpg');
loader.promise
.then(img => console.log('预加载完成', img))
.catch(err => console.log('被取消或失败', err));
// 3 秒后取消(例如用户导航离开)
setTimeout(() => loader.abort(), 3000);
⚠️ 注意:直接设置 img.src 不可取消
new Image().src = url 是一个“火-and-forget”操作,浏览器会立即发起请求,且没有标准 API 能中止它。即使后续删除 img 元素或设 src = '',请求可能仍在后台进行(取决于浏览器实现)。所以不要依赖这种方式做可取消预加载。
? 进阶技巧:复用 signal 控制多个图片
如果要批量预加载并统一取消,可共用一个 AbortController:
- 创建一个 controller,传给每个
fetch的{ signal } - 任意时刻调一次
controller.abort(),所有关联的 fetch 都会中断 - 适合页面级预加载队列、懒加载管理器等场景
? 补充说明:为什么不用 XMLHttpRequest?
虽然 XMLHttpRequest 有 .abort() 方法,但它已属旧标准,缺乏 Promise 支持,且与现代信号机制不兼容。用 fetch + AbortController 更简洁、可组合、符合当前最佳实践。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










