闭包通过封装私有状态实现多文件上传的上下文隔离与断点续传,需配合localStorage或服务端uploadId持久化进度映射;其核心作用是状态隔离与生命周期绑定,而非直接持久化。

闭包本身不直接“保存进度映射”,但它能安全地封装和持久化上传切片的状态(如已上传的分片索引、MD5、状态标记等),配合 localStorage / IndexedDB 或服务端记录,实现断点续传所需的上下文隔离与状态延续。
用闭包维持每个文件的独立上传上下文
多个文件同时上传时,每个文件需维护自己的切片队列、已传索引、重试计数等。闭包可将这些变量私有化,避免全局污染或互相干扰:
function createUploader(file, options) {
const { chunkSize = 1024 * 1024 } = options;
const totalChunks = Math.ceil(file.size / chunkSize);
// ✅ 闭包内私有状态:仅该上传实例可访问
const uploadedMap = new Map(); // key: chunkIndex, value: { status: 'success' | 'error', uploadId }
const pendingQueue = Array.from({ length: totalChunks }, (_, i) => i);
<p>return {
async uploadNextChunk() {
const index = pendingQueue.shift();
if (index === undefined) return;</p><pre class="brush:php;toolbar:false;"> try {
const blob = file.slice(index * chunkSize, (index + 1) * chunkSize);
const res = await uploadChunk(blob, file.name, index, uploadedMap.size);
uploadedMap.set(index, { status: 'success', uploadId: res.uploadId });
} catch (err) {
uploadedMap.set(index, { status: 'error', error: err.message });
pendingQueue.push(index); // 放回队尾重试
}
},
getProgress() {
return { total: totalChunks, uploaded: uploadedMap.size };
},
getUploadedIndices() {
return Array.from(uploadedMap.keys()).filter(k => uploadedMap.get(k).status === 'success');
}}; }
// 每个文件获得独立状态空间 const uploaderA = createUploader(fileA, { chunkSize: 2 1024 1024 }); const uploaderB = createUploader(fileB, { chunkSize: 512 * 1024 });
结合 localStorage 持久化切片进度映射
页面刷新后需恢复上传状态,闭包内部可封装序列化/反序列化逻辑,把 uploadedMap 映射存入 localStorage,并自动恢复:
✅ 关键点:用文件唯一标识(如文件名+最后修改时间+大小)生成 key,避免冲突
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
- 上传前:从 localStorage 读取已有进度,初始化
uploadedMap和pendingQueue - 每成功传一个切片:更新
uploadedMap并同步写入 localStorage(建议防抖写入) - 上传完成或取消时:清除对应 key 的 localStorage 记录
服务端协同:用 uploadId 绑定客户端切片状态
纯前端存储不可靠(用户清缓存、换设备)。更健壮的做法是:首次上传时向服务端申请一个 uploadId,后续所有切片请求携带该 ID;服务端记录每个切片的接收状态。此时闭包的作用是:
- 缓存这个
uploadId,确保所有切片请求使用同一 ID - 在内存中暂存已确认成功的切片索引,用于跳过重复上传(幂等控制)
- 封装「查询服务端已传切片列表」的逻辑,恢复本地
uploadedMap
例如:await fetch(`/api/chunk/status?uploadId=${uploadId}`) 返回 [0,2,3,5],则初始化 uploadedMap 并过滤掉这些索引。
注意:闭包不是万能的,需搭配合适存储策略
闭包只解决“状态隔离”和“生命周期绑定”问题,不解决持久化。实际项目中应按场景选择:
- 单页短期上传 → 闭包 + 内存 Map 即可
- 需支持刷新续传 → 闭包 + localStorage(含防篡改校验)
- 多端/长期任务 → 闭包 + 服务端 uploadId 状态 + 客户端轻量缓存
- 大文件/高可靠性 → 加入 IndexedDB 存储切片二进制元数据(如 offset、hash、加密 salt)

















