Chrome中IndexedDB分页查询报错:IDBCursor.continue执行失败
IndexedDB分页查询报错修复方案
问题描述
在Chrome中使用IndexedDB(配合idb库)实现分页查询,编写TypeScript代码时触发以下错误:
caught (in promise) DOMException: Failed to execute 'continue' on 'IDBCursor': The cursor is being iterated or has iterated past its end.
原核心分页函数代码:
export async function getPage<T>(page: number, pageSize: number): Promise<T[]> { let transaction = (await db).transaction(["prompt"], "readonly"); let store = transaction.objectStore("prompt"); const cursor = await store.index("promptIdIndex").openCursor(null,'next'); let offset = (page - 1) * pageSize; const data: T[] = []; while (cursor && offset > 0) { if(cursor && cursor.key){ cursor.advance(offset); offset -= cursor.key as number; } } for (let i = 0; cursor && i < pageSize; i++) { if(cursor && cursor.key){ data.push(cursor.value); cursor.continue(); } } return data; }
尝试增加游标状态检查条件后,问题仍未解决。
错误原因
- 异步操作未正确等待:
cursor.advance()和cursor.continue()都是异步操作,原代码同步调用后直接复用游标,此时游标状态尚未更新,后续操作时游标可能处于迭代中或已到末尾。 - 偏移量逻辑错误:
offset -= cursor.key as number的计算逻辑完全错误,advance(n)的作用是跳过n条记录,而非基于key值做减法,这会导致游标移动完全不符合分页预期。
修复后的代码
export async function getPage<T>(page: number, pageSize: number): Promise<T[]> { const dbInstance = await db; const transaction = dbInstance.transaction(["prompt"], "readonly"); const store = transaction.objectStore("prompt"); let cursor = await store.index("promptIdIndex").openCursor(null, 'next'); const offset = (page - 1) * pageSize; const data: T[] = []; // 跳过指定偏移量的记录 if (offset > 0 && cursor) { cursor = await cursor.advance(offset); } // 读取当前页数据 let count = 0; while (cursor && count < pageSize) { data.push(cursor.value as T); cursor = await cursor.continue(); count++; } return data; }
关键改动说明
- 所有游标移动操作(
advance、continue)都添加await,确保游标状态更新后再执行下一步。 - 简化偏移量处理:直接调用
cursor.advance(offset)跳过指定数量的记录,删除错误的key值计算逻辑。 - 改用
while循环读取页数据,每次移动游标后检查状态,避免在游标已到末尾时调用continue。
内容的提问来源于stack exchange,提问作者spark
相关产品推荐
相关产品推荐

