indexeddb 可作为本地缓存层可靠暂存游戏存档并智能同步,需设计含 id、data、timestamp、syncstatus 和 version 的结构,封装 promise 化仓库支持 save、getpending、marksynced 等操作,实现离线优先保存与后台静默同步,并在启动时按 syncstatus 和 timestamp 安全恢复。

IndexedDB 可以作为本地缓存层,在网络不可用或同步延迟时暂存游戏存档,等网络恢复后再上传至云端。关键不是“替代云端”,而是“可靠暂存 + 智能同步”。
设计带版本和状态标记的存档结构
存档数据不能只存游戏状态,还要附带元信息,方便后续比对、去重和冲突判断:
- id:用户唯一标识(如 userId 或 deviceId + gameKey 组合)
- data:序列化的游戏状态(建议用 JSON.stringify,避免直接存函数或 undefined)
-
timestamp:本地保存时间(
Date.now()),用于判断新旧 -
syncStatus:枚举值,如
"pending"(待同步)、"synced"、"failed" - version:可选,配合服务端 ETag 或自增 revision,用于检测冲突
示例对象:
{ "id": "player_123_game_zelda", "data": "{\"level\":12,\"items\":[\"sword\",\"shield\"]}", "timestamp": 1718234567890, "syncStatus": "pending", "version": 5 }
用 IndexedDB 封装一个可靠的存档仓库
推荐封装成 Promise 化的工具类,避免重复打开数据库、处理事务失败等细节:
- 初始化时用
indexedDB.open创建名为"gameSaveDB"的库,版本设为 1 - 建立 objectStore
"saves",主键为id,并添加syncStatus和timestamp索引,便于查询待同步项 -
save()方法:写入或更新记录,自动设syncStatus: "pending" -
getPending()方法:用index.get(IDBKeyRange.only("pending"))批量获取未同步项 -
markSynced(id)和markFailed(id):仅更新状态字段,不重写整个 data
离线优先保存 + 后台静默同步
用户触发存档(如退出关卡、点击“保存”)时,立即写入 IndexedDB 并返回成功,不等待网络:
- 调用
save({ id, data }),成功后 UI 显示“已缓存”而非“已同步” - 另起一个轻量级同步任务(如
navigator.onLine监听 + 定时轮询),批量取出syncStatus === "pending"的记录 - 逐条 POST 到云端接口;成功则调用
markSynced(id);失败(如 409 冲突、503 服务不可用)则设为"failed",并记录错误原因(可选) - 冲突时(如服务端版本更新),可选择覆盖、合并或提示用户手动选择 —— 这部分逻辑在服务端或客户端决策,IndexedDB 只负责暂存原始版本
启动时恢复 + 防覆盖误操作
游戏加载时,优先读取 IndexedDB 中 syncStatus === "synced" 的最新有效存档(按 timestamp 排序取最大):
- 若找到,直接还原游戏状态,并发起一次后台校验:GET 对应云端存档,比对
version或ETag,如有更新则拉取并覆盖本地"synced"记录 - 若只有
"pending"或"failed"记录,说明上次没同步成功,可提示“检测到本地存档未上传,是否尝试恢复?” - 禁止自动覆盖——比如用户在 A 设备存档后,在 B 设备联网加载了旧版,再切回 A 设备时,不要用本地 pending 覆盖云端 synced,而应保留两者供用户选择
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











