allDone回调是唯一可靠统计入口,它在全部文件上传请求完成(无论成功或失败)后触发一次,参数obj包含total、successful、failed、aborted等最终结果字段,其他回调无法准确统计。
allDone 回调是唯一可靠统计入口
layui 的 upload 组件不提供实时的「已成功/失败总数」变量,所有统计必须依赖 alldone 回调。它在**全部文件上传请求完成(无论成功或失败)后触发一次**,参数 obj 里才包含最终结果字段:obj.total、obj.successful、obj.failed、obj.aborted。
常见错误是试图在 done 或 error 里累加计数——这会漏掉并发场景下的竞态问题,比如两个 done 几乎同时执行,变量自增可能丢失一次。
-
obj.total是本次选择的所有文件数(含被拦截、未触发上传的不算) -
obj.successful只统计返回 HTTP 200 且响应体code === 0的文件(Layui 默认约定) -
obj.failed包含网络错误、超时、非 200 响应等;obj.aborted是主动取消(如调用obj.abort())
number 参数影响 total 但不影响 successful 计算逻辑
number: 5 表示「最多同时发起 5 个并发请求」,剩余文件会排队。这个限制只改变上传节奏,不改变 allDone 中的 total 值——它仍等于用户最初选中的全部文件数。
例如:用户选了 8 个文件,number: 3,那么 obj.total === 8,obj.successful 是最终真正成功入库的个数(可能是 8,也可能是 7,取决于每个请求的后端响应)。
注意:number 不是「最大允许上传数」,它和限制选择数量无关,纯属并发控制。
前端无法准确区分 failed 和 aborted,需后端配合
Layui 把请求异常(如 500、断网)、响应格式错误(如后端返回非 JSON)、甚至跨域失败都归为 failed;而 aborted 仅由显式调用 obj.abort(index) 触发。但用户点击「取消上传」按钮时,如果没手动调用 abort,这部分文件会被计入 failed,而非 aborted。
所以仅靠 allDone 的字段,你无法判断某个失败是「用户主动放弃」还是「服务端崩了」。解决办法:
- 在 UI 上提供「取消」按钮,并确保点击时执行
obj.abort(index) - 后端返回统一结构,例如
{code: -1, msg: "用户取消"},前端在done里识别并单独计数 - 避免依赖
obj.aborted做业务判断,它不可靠
统计显示要等 allDone,别在 progress 里提前渲染
有人在 progress 回调里判断 n === 100 就更新成功数,这是错的——progress 到 100% 只表示浏览器发完了,后端还没处理完,done 都没触发,更别说 allDone。
正确做法:所有统计文案(如「共 5 个,成功 3 个,失败 2 个」)必须放在 allDone 回调里更新 DOM。如果需要中间态反馈,可用「上传中…(3/5)」这种基于当前进度的描述,但总数统计以 allDone 为准。
容易被忽略的是:allDone 不保证按文件顺序触发,它只保证「全部结束」,所以不要假设 index 或顺序可用于累计逻辑。











