indexeddb 游标通过 opencursor() 等方法逐步遍历海量数据,支持范围查询(idbkeyrange)、反向遍历("prev")、分块处理防阻塞,并自动延长事务生命周期直至游标耗尽。

IndexedDB 的游标(Cursor)是遍历海量数据集的核心机制,它避免了一次性加载全部数据到内存,适合处理成千上万甚至更多条记录。关键在于用 openCursor() 或 openKeyCursor() 获取游标对象,再通过 cursor.continue() 逐步移动,配合事务生命周期管理。
用 openCursor() 遍历所有记录
最常用的方式是调用 objectStore 的 openCursor() 方法,它返回一个 Promise 包裹的 IDBRequest,成功后可在 onsuccess 中获取游标对象。游标默认从第一条记录开始,每次处理完一条就调用 continue() 跳到下一条。
- 游标本身有
key、primaryKey和value属性,分别对应索引键、主键和整条数据 - 当游标移到末尾时,
event.target.result会变成null,此时应停止递归或循环 - 不要在游标遍历中途显式结束事务;IndexedDB 会自动延长事务生命周期,直到游标耗尽或显式中止
按范围或条件限制遍历(使用 KeyRange)
直接遍历全量效率低,实际中常结合 IDBKeyRange 精准定位起始/结束位置。比如只读取 2023 年之后的订单:
- 用
IDBKeyRange.lowerBound(new Date('2023-01-01'))构造范围,传给openCursor(range) - 也可用
upperBound、bound或only实现区间、单值匹配等逻辑 - 若基于非主键字段查询,需确保该字段已建索引,并调用索引的
openCursor()(如index.openCursor(range))
批量处理 + 防阻塞:分块与 yield
一次性处理几万条记录容易导致页面卡顿。推荐每批处理 100–500 条后,用 setTimeout 或 requestIdleCallback 让出主线程:
- 维护一个计数器,在
onsuccess中累加,达到阈值就setTimeout(() => cursor.continue(), 0) - 更现代的做法是封装为异步迭代器,用
await+yield控制节奏(需手动实现或借助库如idb) - 注意:不能在游标活跃时关闭数据库连接或删除 objectStore,否则游标立即失效
游标方向与反向遍历
游标默认正向("next"),也可设为 "prev" 反向遍历,适用于“最新 10 条”这类需求:
- 调用
openCursor(null, "prev")即可,null表示无范围限制 - 反向时
cursor.continue()会往更小的键移动,首条是最大键对应的记录 - 若配合
IDBKeyRange.upperBound(maxKey, true)(第三个参数true表示不包含边界),可高效截取倒序前 N 条
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











