IndexedDB 是异步本地数据库,所有操作需在事务中通过事件或 Promise 处理;打开时用 indexedDB.open(),升级在 upgradeneeded 中建表;增删改查须指定 readonly/readwrite 事务;推荐 Promise 封装请求并用 async/await 管理;大数据量用游标遍历,配合 IDBKeyRange 范围查询。

IndexedDB 是浏览器提供的本地数据库,所有操作都是异步的,不能像同步代码那样直接获取返回值。核心在于:它基于事件驱动和 Promise(现代写法),必须通过回调或 await 等待操作完成,否则读不到刚写入的数据。
打开数据库并处理版本升级
调用 indexedDB.open() 会立即返回一个 IDBOpenDBRequest 对象,但实际打开结果要等 success 或 error 事件触发。如果数据库不存在,或 version 参数大于当前版本,会触发 upgradeneeded 事件——这是唯一能创建/修改对象存储(objectStore)的地方。
- 在 upgradeneeded 回调中用 db.createObjectStore() 创建表,或 store.createIndex() 建索引
- 不能在 success 回调里建表,否则报错 "InvalidStateError"
- 升级时不要删除旧数据,除非显式调用 db.deleteObjectStore()
增删改查都需先开启事务
所有数据操作(add、put、delete、get、cursor 遍历)都必须在事务(IDBTransaction)内进行。事务由 db.transaction() 创建,指定对象存储名和模式("readonly" 或 "readwrite")。
- 只读操作用 "readonly",性能更好;写操作必须用 "readwrite"
- 事务生命周期绑定到事件循环:事务在所有请求发起后自动关闭,除非显式延长(如用 cursor.continue())
- 事务失败会触发 abort 事件,成功则触发 complete 事件(注意:complete 不代表所有请求都成功,只是没被中止)
用 Promise 封装请求更易管理
原生 IndexedDB 基于事件,嵌套回调易出错。推荐封装成 Promise,配合 async/await 使用:
立即学习“Java免费学习笔记(深入)”;
- 对 IDBRequest 对象监听 success/error 事件,resolve/reject 对应结果
- 例如封装 get():返回 Promise<value>;封装 add():返回 Promise<key>
- 批量操作可用 Promise.all() 并行提交多个请求(但它们仍在同一事务中)
游标遍历适合大数据量查询
当需要按范围、顺序或条件批量读取时,用 openCursor() 或 openKeyCursor() 比多次 get() 更高效。游标本身也是异步的,每次 advance 或 continue 都要等 success 事件。
- 用 IDBKeyRange 定义范围,如 IDBKeyRange.bound("a", "z")
- 在 cursor 的 success 回调中检查 event.target.result 是否为 null,为 null 表示遍历结束
- 避免在游标循环中执行耗时同步操作,否则阻塞主线程










