闭包通过封装运行时上下文实现状态持久化感知,而非直接保存数据;它统一管理IndexedDB实例、同步队列与网络监听器,暴露有限接口,并封装三态生命周期、冲突策略及多标签页协同逻辑。

闭包本身不能持久化状态,它只是让函数能记住并访问其词法作用域中的变量。真正实现“状态持久化感知”的离线存储同步引擎,靠的是闭包对本地存储实例、同步队列、网络状态监听器等运行时上下文的封装和组织,而不是靠它保存数据本身。
用闭包封装存储与同步上下文
把 IndexedDB 实例、待同步草稿列表、online/offline 监听器统一放在一个立即执行函数中,对外只暴露有限接口:
- 内部维护一个 syncQueue 数组,存未提交草稿(含 id、content、updatedAt、clientOpId)
- 用 Dexie.js 数据库实例 作为唯一数据源,所有读写都走它
- 监听
window.addEventListener('online', ...),触发时调用内部同步函数,不暴露原始事件监听器 - 导出的
saveDraft()和triggerSync()都是闭包内定义的函数,天然持有上述上下文
用闭包管理三态生命周期逻辑
每条草稿的状态流转(draft → syncing → synced)需要原子性控制,闭包可封装状态检查与更新逻辑:
-
markAsSyncing(id):先查数据库确认 isSynced === false,再更新为 syncing 状态,避免并发重复提交 -
markAsSynced(id, serverId):更新 isSynced = true,并写入服务端返回的 ID,同时从 syncQueue 移除 -
markAsFailed(id, error):保留草稿内容,仅更新 syncError 字段,供 UI 显示重试按钮 - 这些函数不依赖外部传入状态,所有判断和操作都在闭包作用域内完成
用闭包隔离冲突处理策略
内容哈希比对、clientOpId 生成、用户合并提示等逻辑,适合用闭包封装成可配置的策略模块:
- 内部预设
generateClientOpId():基于 Date.now() + Math.random() 生成唯一标识,首次生成后缓存在闭包变量中 - 内置
computeContentHash(content):用轻量 SHA-256 实现(如 crypto.subtle.digest),不依赖全局变量 - 当服务端返回 409 冲突时,闭包内触发自定义事件
conflictDetected,携带本地内容与远程内容,由上层决定是否弹窗 - 策略函数彼此共享同一套哈希/ID 工具,无需重复初始化
用闭包协调多标签页一致性
浏览器多标签页共享 localStorage,但 IndexedDB 不自动同步。闭包可配合 storage event 做轻量协同:
- 在闭包内监听
window.addEventListener('storage', ...),捕获其他标签页发出的同步动作信号 - 例如:标签页 A 发起同步后,向 localStorage 写入
sync:triggered:true,标签页 B 捕获后主动刷新自己的 syncQueue 视图 - 所有事件监听和响应逻辑被封装在闭包中,避免污染全局作用域或重复绑定
- 不直接跨标签页同步数据,只同步“该不该刷新”这个意图,保持职责清晰

















