Layui上传组件实现多文件同时上传并行限制

作者:技术拾光

时间:2026-07-23

浏览:534

Layui上传组件的number参数仅限制单次选择文件数,并非全局并发上限。并行上传控制需手动实现队列调度,通过obj.upload()逐个调用并维护并发计数器。更稳妥的方案是关闭auto,用原生fetch与Promise.allSettled分批处理,自主掌控并发粒度。

文章目录

在使用 layui 的 upload 组件时,number 参数是最容易让人误解的配置之一。许多开发者看到 number: 3 后,会认为它直接限制了用户总共能上传的文件数量。实际测试中,用户反复点击选择文件按钮,一次性选中 9 个文件,让预期控制失效。

事实上,number 参数的作用范围非常明确:它仅限制每次触发 choose 事件时,通过原生 能够选中的文件数量。也就是说,它只关心“用户点击一次按钮后弹出的文件选择窗口中,最多可以勾选几个文件”。对于之前已经选择的文件、已上传的文件或已删除的文件,它完全不参与。此外,该参数仅在 layui 2.8 及以上版本中生效,2.7 及以下版本不支持。使用 number 必须配合 multiple: true,否则在单文件模式下该参数不起作用。

Layui上传组件实现多文件同时上传并行限制

因此,结论很清晰:number 并非全局计数器,它只是一个“单次选择上限”。用户点击两次选择按钮,每次选择 3 个文件,最终可以累积 6 个待上传文件。

如何控制“同时上传”的并发数量?

layui 默认的上传行为是:每个文件独立发起一个 HTTP 请求(当 auto: true 时)。所谓“同时上传”,实际上是浏览器同时发起多个请求,而浏览器自身对同域名的并发限制(通常为 6 个)并不受 layui 控制。要真正限制上传并发数,需要自行实现队列调度。

核心思路并非阻止用户选择文件,而是控制 obj.upload() 的调用节奏:

  • 将所有待上传文件缓存到一个数组,例如 pendingFiles = []。
  • 定义最大并发数,例如 maxConcurrent = 3。
  • 使用计数器 running = 0 实时追踪当前正在上传的请求数量。
  • 每次调用 obj.upload(index, file) 前,判断 if (running < maxConcurrent),若已达上限则将文件入队等待。
  • 在 done 或 error 回调中执行 running--,然后从队列中取出下一个文件启动上传。

注意:obj.upload() 是 layui 的内部方法,不能直接传入数组,必须逐个调用。队列逻辑需要自行维护。

为什么 acceptNum 和 multiple 也无法解决问题?

layui 2.8+ 新增了 acceptNum 参数,但它与 number 本质相同——仅限制单次选择数量,且对拖拽上传完全无效。通过拖拽添加的文件会绕过所有选择限制,直接进入 choose 回调。而 multiple: true 仅决定文件选择框是否支持多选,与 HTTP 请求的并发调度无关。

此外,浏览器对同域名的并发请求数有默认限制(通常为 6 个),但这并非可配置的“并行上传上限”,不同浏览器表现不一,依赖它来做控制并不可靠。

更稳妥的方案:关闭 auto,使用 Promise 分批处理

如果需求非常严格,例如必须限制同时只有 3 个上传请求在运行,最佳方案是绕过 layui 的上传流程,改用原生 fetch 配合 Promise.allSettled 自行实现分批调度:

  • 设置 auto: false,在 choose 回调中将所有 File 对象收集到一个数组中。
  • 编写 uploadBatch(files) 函数,每次取 maxConcurrent 个文件,构造 FormData 发送请求。
  • 使用 Promise.allSettled() 等待当前批次完成,再处理下一批。
  • 后端接口需要支持接收 files[] 字段的 multipart 请求。

这种方法可以完全掌控并发粒度,不受 layui 内部上传逻辑的不可控因素影响。代价是需要自行处理进度更新、重试机制和错误聚合,而这也是换取确定性的必要付出。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章