如何将图片加载事件封装为Promise 实现批量同步获取图片尺寸信息
问题修复方案
错误原因
你的代码核心问题是img.src = url的赋值位置错误:
- 只有给Image实例的src属性赋值后,浏览器才会发起图片资源请求,加载完成后才会触发
load事件 - 你把
img.src = url写在了load事件的回调函数内部,导致永远不会触发load事件,Promise持续处于pending状态,所以await Promise.all会一直等待,不会执行后续逻辑
修复后可运行代码
const array = [ "https://via.placeholder.com/350x150", "https://via.placeholder.com/650x250", "https://via.placeholder.com/350x150", "https://via.placeholder.com/650x250", "https://via.placeholder.com/150x550", "https://via.placeholder.com/510x450", "https://via.placeholder.com/800x800" ] function doSomethingAsync(url) { return new Promise((resolve, reject) => { const img = new Image() // 监听加载成功事件 img.addEventListener('load', function() { const isWide = img.width > img.height const isTall = img.height > img.width resolve({ url, isWide, isTall, width: img.width, height: img.height }) }) // 增加加载失败的错误处理,避免Promise永远pending img.addEventListener('error', (err) => { reject(new Error(`图片加载失败: ${url}`)) }) // 赋值src触发图片加载,注意要放在事件监听之后 img.src = url }) } async function doAsync() { try { console.log('before promise all') const results = await Promise.all(array.map(url => doSomethingAsync(url))) console.log('after promise all', results) // 后续逻辑写在这里即可 } catch (err) { // 捕获任意一张图片加载失败的错误 console.error('批量处理图片出错:', err) } } doAsync()
优化说明
- 调整了
img.src = url的位置,放在事件监听之后,赋值后即可触发图片加载流程 - 新增了
error事件监听,加载失败时主动reject,避免Promise无限pending - 补充了
try/catch捕获批量处理过程中的异常,避免单张图片加载失败导致整个逻辑崩溃 - 用
Array.map简化了Promise数组的生成逻辑,代码更简洁
内容的提问来源于stack exchange,提问作者aspirinemaga
相关产品推荐
相关产品推荐

