IndexedDB 原生不支持链式调用,需用 Promise 封装 IDBRequest 并结合 async/await 实现顺序流水线;支持并行请求(Promise.all)、游标分批遍历及事务安全的读写控制。

IndexedDB 本身不提供链式调用能力,它的原生 API 是事件驱动的;但你可以通过 Promise 封装 + async/await 构建清晰、可控的异步流水线——关键不是“强行链”,而是让每一步自然等待上一步完成,同时保持事务安全和错误可捕获。
封装基础操作为 Promise
所有 IndexedDB 请求(如 open、add、get、cursor)都返回 IDBRequest 对象,监听其 success/error 即可转为 Promise:
-
openDB(name, version):返回 Promise
,在 upgradeneeded 中建表,success 中 resolve 数据库实例 -
getStore(db, storeName, mode = 'readonly'):返回 Promise
,确保从有效事务中获取 store -
putData(store, value):返回 Promise
,自动处理事务生命周期(建议复用同一事务做批量写) -
getData(store, key):返回 Promise
,失败时 reject 或 resolve undefined 可按需设计
用 async/await 实现顺序流水线
适合有明确依赖关系的操作,比如“先查用户 → 再查其订单 → 最后更新用户最后登录时间”:
- 每步 await 一个 Promise,逻辑线性、调试友好
- 整个流程可包在一个立即执行函数或方法中,统一 try/catch 错误
- 注意:不要跨事务复用 objectStore;每个 store 获取应绑定到当前事务
- 示例片段:const db = await openDB('myApp', 2);
const tx = db.transaction(['users', 'orders'], 'readonly');
const user = await getData(tx.objectStore('users'), 123);
const orders = await getAllByIndex(tx.objectStore('orders'), 'userId', user.id);
const writeTx = db.transaction(['users'], 'readwrite');
await putData(writeTx.objectStore('users'), {...user, lastLogin: Date.now()});
并行请求 + 合并结果(非严格链式但更高效)
当多个查询无依赖、可独立执行时,用 Promise.all 并发发起,比串行快得多:
- 仍需确保它们属于同一事务(只读事务可安全并发操作多个 store)
- 例如:同时拉取用户资料、通知数、未读消息列表
- 失败时 Promise.all 会短路,可用 Promise.allSettled 保全部分结果
- 注意游标遍历不能直接放进 Promise.all —— 它是迭代过程,需封装成返回 Promise
> 的函数
游标遍历与分批处理的流水控制
查大数据量时,openCursor 是核心,但它本身是事件循环驱动的,需手动“续跑”:
- 封装 cursor 遍历为 Promise
:内部递归调用 continue(),直到 result 为 null - 加节流:每处理 N 条后 await Promise.resolve(),避免长任务阻塞主线程
- 配合 IDBKeyRange 实现分页效果,例如每次取 100 条,再触发下一批请求
- 若需边查边写(如迁移数据),应在 readwrite 事务中用两个 store 交替操作,注意避免死锁

















