离线数据同步需分批写入并让出主线程控制权,推荐用queueMicrotask;记录断点、标记状态、捕获单条异常、空闲时调度,并每批新建事务确保顺序与一致性。

离线数据同步时批量写入容易阻塞主线程,导致页面卡顿甚至无响应。关键是在写入过程中主动让出控制权,用 setTimeout、queueMicrotask 或 requestIdleCallback 拆分任务,同时确保数据一致性与顺序不乱。
按批次切分写入,每批后让出主线程
不要一次性遍历全部待同步数据,而是设定合理批次大小(如 20–50 条),每写完一批就调用 setTimeout(..., 0) 或 queueMicrotask 推迟下一批执行:
-
推荐用
queueMicrotask:微任务时机更及时,适合对延迟敏感的场景,且能保证同一批次内操作原子性 - 用
setTimeout(..., 0)</strong> 更稳妥</li> <li>避免在循环中直接递归调用(如 <code>writeNextBatch()
),防止调用栈过深;改用迭代 + 异步调度
维护写入状态,支持断点续传
离线同步可能中途被中断(用户关闭页签、网络恢复触发重试等),需记录当前进度:
- 每次完成一批写入后,将已处理的 ID 列表或最后一条时间戳/序号存入 IndexedDB 或 localStorage
- 下次同步前先读取断点位置,跳过已成功写入的数据
- 对每条记录标记
sync_status: 'pending' | 'synced' | 'failed',便于重试失败项
写入失败时降级处理,不中断整体流程
单条写入失败(如存储空间不足、字段校验不通过)不应导致整个批次或同步任务终止:
立即学习“Java免费学习笔记(深入)”;
- 捕获每条写入的异常(如
await store.add(item)的 reject),记录错误但继续处理下一条 - 将失败项收集到单独队列,同步完成后统一上报或加入重试队列
- 可设置最大重试次数(如 3 次),超限则标记为
sync_failed并通知用户
结合空闲时间调度,提升用户体验
若页面处于空闲状态(用户未交互、无动画、CPU 负载低),可用 requestIdleCallback 更友好地推进同步:
- 在空闲回调中执行一批写入,检查
deadline.timeRemaining() > 1再决定是否继续 - 若空闲时间不足,把剩余任务暂存并等待下次空闲回调
- 注意兼容性:Safari 对
requestIdleCallback支持有限,需降级到setTimeout
不复杂但容易忽略的是写入顺序和事务边界——IndexedDB 的 transaction 不跨异步任务,每批必须新建事务;同时确保主键或时间戳唯一,避免重复写入或覆盖。


















