数据同步与恢复
网络会把“服务端是否完成”与“客户端是否知道”分开。同步系统因此需要稳定操作身份、明确确认点和可恢复日志:请求失败不代表业务没发生,进度100%也不代表已提交,恢复必须先对账再继续。
核心模型
网络会把“服务端是否完成”与“客户端是否知道”分开。同步系统因此需要稳定操作身份、明确确认点和可恢复日志:请求失败不代表业务没发生,进度100%也不代表已提交,恢复必须先对账再继续。
原理与机制
上传进度不是提交证明
大文件按 Blob 范围切片,以上传会话、分片编号和内容校验约定身份,受控并发避免同时读完整文件。重连查询服务端已确认分片,只补缺失部分;总体进度按唯一字节加权,不把重试重复累计。XHR upload progress 描述传输过程,之后还有校验、合并和持久化。完成接口需要原子记录会话结果,响应丢失后重放同一键返回原结果。授权、限额、真实内容检查和安全文件名属于服务端,哈希匹配也不能替代恶意内容检查。
自动保存维护三份时间线
当前草稿、已确认基线、发送中的快照必须分开。发出 V1 后用户又编辑成 V2,V1 成功只推进基线,不能覆盖 V2 或把全部草稿标成已保存。后续请求合并或串行,并带新基线版本。服务端用强 ETag/If-Match 或等价版本做原子条件更新,版本冲突返回412等明确结果;共同基线、远端和本地三方合并,无法安全合并就让用户决策。客户端时钟和防抖都不能代替原子比较。
离线队列记录意图与确认
草稿保证可继续编辑,outbox 则记录待执行操作;每项有稳定 ID、账号作用域、资源版本、载荷与状态。本地事务完成后才显示本地已保存,服务端确认后才显示同步完成。提交成功但响应丢失时,同一用户作用域内的幂等键防重复;依赖操作串行,独立操作可受控并发。退出或切账号时不能把旧队列借新身份发送;撤权、冲突与永久业务错误应进入显式状态,而非无限重放。
本地持久化也需要恢复协议
IndexedDB 在无待处理请求且当前活动阶段未再放入请求时可自动提交,不能开事务后等待网络再回来写。它与 OPFS 不是同一个原子事务:可以先写临时文件,再提交带状态的元数据,启动时对账孤立文件和缺文件记录。配额、站点清理与设备故障意味着本地保存不是永不丢失,需区分可重建缓存与必须导出的原始资料。后台同步或 service worker 只改善机会,页面重开仍要主动恢复队列。
实时传输靠游标恢复业务连续性
选择轮询、SSE 或 WebSocket 先看单向/双向、延迟和基础设施。连接内有序不代表跨重连无丢失,事件 ID、已确认游标与去重集合才支撑补拉;超出保留窗口需取新快照,未读数由服务端权威计算。重连使用有上限的退避与抖动,鉴权失败停止盲试;慢消费者有队列上限、合并渲染和降级。多标签共享连接增加选主、租约与短时双主处理,BroadcastChannel 自身不提供互斥。
最小示例
javascript结果 base=B、版本2,但 draft 仍为C、dirty=true。这里约定一次只有一个在途保存,并以文本相等判断是否脏;丰富文档应改用编辑修订号或内容契约。服务端仍需独立原子校验 sent.baseVersion,纯函数无法防远端覆盖。
核验:Node v24.19.0:旧保存确认保留新草稿、推进基线、保持dirty及输入不变断言通过;不覆盖服务端条件写入或存储事务。
边界与取舍
边界
- navigator.onLine 为真只表明浏览器的连接判断,不能证明目标服务可达,更不能证明队列已确认。
- “服务端成功、响应丢失”必须纳入测试;新建幂等键后重试会把同一意图当成新操作。
- 离线删除遇到远端修改属于业务冲突;CRDT、WebSocket 或重试都不会替你决定哪方应赢。
取舍
- 保留操作日志便于恢复与审计,却增加存储和隐私成本;按业务保留窗口压缩并保护敏感队列。
- 串行保存容易维护基线,吞吐较低;并发需明确独立性、顺序和提交条件,不能只增加并发数。
口述示范
我会把传输、暂存和确认分开,用操作 ID 防重复、版本防覆盖、日志与游标补缺口。每个恢复动作都先核对账号与服务端事实,并把冲突、失败和本地已保存清楚展示。
章节练习
参考来源与核验边界
- MDN:If-Match · 核验 2026-10-04
- MDN:IDBTransaction · 核验 2026-10-04
- MDN:OPFS · 核验 2026-10-04
- MDN:Using Server-Sent Events · 核验 2026-10-04
2026-10-04 核验;后台同步、OPFS 与持久化策略需按浏览器支持和配额实测。TranslateFlow 仅为假设设计练习,未声称已有跨存储实现。
内容版本:2026-10-04.2 · 题目和来源 ID 保持原样,本站不将面经标签解释为企业官方出题或高频保证。