IDBCursor 的 direction: "prev" 可倒序遍历,但必须基于已排序的主键或索引;支持通过 IDBKeyRange.upperBound() 配合 direction: "prev" 实现从某点倒序查询,如获取时间戳≤指定值的最近N条记录。

IDBCursor 的 direction 参数可直接控制遍历顺序,设为 "prev" 即可倒序遍历——但需注意前提:游标必须基于一个**已排序的索引或主键范围**,否则倒序无意义。
确保游标有明确排序依据
倒序要求底层数据能按某字段单调排列。IDB 不支持 SQL 式任意 ORDER BY,必须依赖:
- 对象存储(Object Store)的主键(keyPath),若主键是递增数字或时间戳,
direction: "prev"会从最大值往最小值走 - 显式创建的索引(如按
createdAt字段),且该索引已声明unique: false和multiEntry: false
使用 openCursor() 指定方向
在 objectStore 或 index 上调用时传入 { direction: "prev" }:
const transaction = db.transaction("logs", "readonly");
const store = transaction.objectStore("logs");
// 倒序遍历全部记录(按主键降序)
store.openCursor(null, "prev").onsuccess = function(e) {
const cursor = e.target.result;
if (cursor) {
console.log(cursor.key, cursor.value); // 先输出最大 key,再逐次减小
cursor.continue(); // 继续上一条(更小的 key)
}
};
结合 keyRange 实现“从某点倒序”
若只需倒序查最近 10 条,可用 IDBKeyRange.upperBound() 锁定起点:
-
IDBKeyRange.upperBound(Date.now(), true):排除当前时刻,取更早的记录 - 配合
direction: "prev",游标从紧邻的前一个 key 开始向上(时间上更早)回溯
示例:查 createdAt 索引下,时间 ≤ 2024-06-01 的最后 5 条
const range = IDBKeyRange.upperBound(new Date("2024-06-01"));
const index = store.index("createdAt");
index.openCursor(range, "prev").onsuccess = function(e) {
const cursor = e.target.result;
if (cursor && count < 5) {
console.log(cursor.value);
count++;
cursor.continue();
}
};
注意游标生命周期与错误边界
"prev" 方向下,cursor.continue() 会不断尝试获取“前一个”记录,直到 key 超出范围,此时 result 为 null。常见疏漏:
- 未检查
cursor是否存在就调用cursor.continue(),导致报错 - 在
"prev"游标中误用cursor.advance(1)(它仍按正向跳,与方向无关) - 索引字段含重复值时,
"prev"仍按 key(而非 value)排序,相同索引值的记录顺序由主键决定

















