uniCloud.uploadFile 不能直接 Promise.all 并发调用,因平台原生上传通道有并发数硬限制(如微信小程序≤3),超限会导致静默失败;应采用队列模式(最大并发3)、状态隔离、H5中转及端侧压缩,并注意H5 blob处理和iOS onUploadProgress注册时机。

uniCloud.uploadFile 不能直接 Promise.all 并发调用
直接用 Promise.all 包裹多个 uniCloud.uploadFile 调用,在 H5 和部分 App 环境看似能跑通,但实际会触发静默失败或进度丢失——尤其在弱网、低端安卓机上。根本原因是 uniCloud.uploadFile 内部依赖平台原生上传通道,而该通道对并发连接数有硬限制(微信小程序通常 ≤3,iOS 更敏感),超出后新任务会被丢弃,且无错误回调。
实操建议:
- 必须用队列模式控制并发,推荐最大并发数设为
3 - 不要用
forEach+async/await,闭包容易错乱索引,改用for (let i = 0; i 显式索引 - 每个上传任务必须立即绑定
onUploadProgress,否则小文件可能瞬间完成,第一帧进度直接跳过 - 失败时需记录
fileIndex和error.message,避免只显示“上传失败”这种无效提示
每张图必须独立维护状态和进度
批量上传时 UI 错乱的根源,是把所有图片的进度往同一个变量里塞。比如写 this.currentProgress = res.progress,结果第 5 张图上传完,界面上所有图片都显示“100%”。这不是 bug,是状态没隔离。
实操建议:
- 初始化图片列表时,每个对象至少包含:
id(唯一字符串)、localPath、status('pending'/'uploading'/'success'/'fail')、progress(初始 0) -
onUploadProgress回调里,必须通过索引或id更新对应项:this.imageList[i].progress = res.progress - 成功回调中,用
res.fileID替换localPath,失败则保留原始路径并标记status: 'fail' - 切忌用全局变量汇总进度,用户需要看到“第 2 张 73%”,不是“整体 42%”
H5 端跨域问题必须靠云函数中转
直接在 H5 页面调用 uniCloud.uploadFile 会触发跨域错误,因为浏览器同源策略限制了直传云存储的预签名地址。这不是配置问题,是浏览器能力边界。
实操建议:
- H5 必须走云函数中转:前端把图片
base64或Blob发给云函数,由云函数调用uniCloud.uploadFile - 云函数内需校验文件大小(如限制 ≤5MB)、类型(白名单
['image/jpeg','image/png']) - 返回结构统一为:
{ index: 0, fileID: 'xxx', url: 'https://xxx' },方便前端按序更新状态 - 别在 H5 端尝试伪造
cloudPath或拼接直传 URL,徒劳且不安全
上传前压缩和尺寸约束要分端处理
uni.chooseImage 返回的 tempFilePaths 在不同平台含义不同:iOS 和 Android 返回的是临时文件路径,可直接传给 uniCloud.uploadFile;但 H5 返回的是 blob: URL,必须先转成 File 对象才能上传。
实操建议:
- 选图时统一加
sizeType: ['compressed'],减少内存压力 - 对 iOS/Android,用
uni.compressImage做二次压缩(质量 70,宽度 ≤1200px);H5 则用canvas压缩,避免compressImage不支持 - 上传前检查单图大小:
uni.getFileInfo获取size,超限(如 >5MB)直接标记status: 'oversize'并跳过上传 - App 端可启用
uni.downloadFile预检网络,避免上传中途断连


















