多图上传顺序异常及await使用报错问题求助
问题分析与解决方案
你的问题核心有两个:
- 标注了
async的uploadImage函数其实没真正等待异步操作完成:内部的FileReader.onload和img.onload都是回调式异步逻辑,没有用Promise包裹,导致函数会立即返回空Promise,await完全起不到等待作用。 - 循环中直接调用
uploadImage会让所有图片的处理并行执行:大文件因为加载、压缩耗时更长,会比小文件晚完成,最终显示顺序就变成了按文件大小排序。
第一步:重构uploadImage为真正的异步函数
用Promise包裹所有异步逻辑,确保函数能正确等待图片加载、压缩完成后再返回结果:
const uploadImage = (file, id) => { return new Promise((resolve, reject) => { if (!file) { resolve(null); return; } const fileReader = new FileReader(); fileReader.onload = () => { const img = new Image(); img.onload = () => { const canvas = document.createElement("canvas"); const MAX_WIDTH = 1000; const MAX_HEIGHT = 1500; let width = img.width; let height = img.height; if (width > height) { width > MAX_WIDTH && (height *= MAX_WIDTH / width, width = MAX_WIDTH); } else { height > MAX_HEIGHT && (width *= MAX_HEIGHT / height, height = MAX_HEIGHT); } canvas.width = width; canvas.height = height; const ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, width, height); const base64Str = canvas.toDataURL("image/jpeg", 90); if (id === 0) { resolve(base64Str); } else { const resultEl = document.getElementById(`product_photo_${id}_result`); resultEl.innerHTML += `<img src="${base64Str}" class="img-thumbnail m-2 product_photo_${id}_base64" style="height: 50px;" />`; resolve(); } }; img.onerror = reject; img.src = fileReader.result; }; fileReader.onerror = reject; fileReader.readAsDataURL(file); }); };
第二步:修改事件监听函数,用await保证顺序执行
把change事件的回调改成async函数,循环内用await调用uploadImage,同时修正循环条件错误(原index <= files.length会取到undefined,改为index < files.length):
document.getElementById("product_photo_1").addEventListener("change", async (event) => { const files = event.target.files; for (let index = 0; index < files.length; index++) { await uploadImage(files[index], 1); } }); document.getElementById("product_photo_2").addEventListener("change", async (event) => { const files = event.target.files; for (let index = 0; index < files.length; index++) { await uploadImage(files[index], 2); } });
额外优化说明
- 用
event.target.files替代重复获取DOM元素,代码更简洁 - 增加了错误捕获逻辑(
onerror时触发reject),可在调用时通过try/catch处理异常 - 用模板字符串替代字符串拼接,可读性更强
修改后,图片会严格按照你选择的顺序依次处理并显示,不会再出现顺序混乱的问题。
内容的提问来源于stack exchange,提问作者user22118880
相关产品推荐
相关产品推荐

