Promise可优雅实现图片异步预加载:封装Image加载为Promise,支持单张加载、Promise.all并行批量加载及reduce串行加载,并可增强超时控制、缓存复用与CORS处理。

Promise 可以优雅地实现图片的异步预加载:创建一个返回 Promise 的函数,内部用 Image 对象加载图片,成功时 resolve,失败时 reject,从而统一处理加载状态和错误。
核心实现:封装单张图片加载为 Promise
利用 Image 对象的 onload 和 onerror 事件,将其包装成 Promise:
function preloadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img); // 加载成功,传回 img 元素
img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
img.src = src; // 触发加载
});
}
这样调用时就能用 .then() 或 async/await 处理结果:
preloadImage('./banner.jpg')
.then(img => console.log('预加载完成', img.width, 'x', img.height))
.catch(err => console.error(err.message));
批量预加载多张图片(按顺序或并行)
使用 Promise.all() 并行加载所有图片,适合「全部就绪后才开始渲染」的场景:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
const urls = ['1.jpg', '2.jpg', '3.jpg'];
Promise.all(urls.map(preloadImage))
.then(images => {
console.log('全部加载完成,共', images.length, '张');
// images 是 Image 实例数组,可直接用于 DOM 插入或缓存
})
.catch(err => console.error('某张图加载失败:', err.message));
若需按顺序加载(如节省内存或控制节奏),可用 reduce 串行化:
urls.reduce((chain, url) =>
chain.then(() => preloadImage(url)),
Promise.resolve()
).then(() => console.log('按序加载完毕'));
实用增强:添加超时、缓存与复用支持
真实项目中建议补充以下能力:
-
超时控制:防止某张图长期 pending,可搭配
AbortController或setTimeout实现 -
简单缓存:用 Map 记录已加载的 URL,避免重复请求(注意:已加载的
Image对象可直接复用,无需再触发 onload) -
自动插入 document:加载成功后可选是否将
img添加到隐藏容器,确保浏览器缓存生效(尤其对后续<img>标签有用)
注意事项与常见问题
预加载图片时需留意:
- 图片跨域时,若服务端未设置
CORS头,img.crossOrigin = 'anonymous'可能导致onerror,但无法获取具体错误信息 - 已加载过的图片再次调用
preloadImage仍会触发onload(因img.src赋值会立即触发,且浏览器缓存响应很快) - 不建议在
preloadImage内部自动插入 DOM;应由业务层决定何时展示,保持职责分离

















