IndexedDB 原生 API 事件驱动、冗长易错,Promise 封装后支持 await,简化 open(自动版本升级、复用连接、声明 objectStore)、CRUD(语义化方法、自动事务)、错误增强(可读提示、耗时监控)及自定义错误处理。
IndexedDB 原生 API 是事件驱动的,写起来冗长又容易出错。用 Promise 封装后,可以像调用 fetch 一样 await 操作,代码更简洁、逻辑更清晰。
封装 open:统一数据库连接管理
数据库打开是所有操作的前提,但 onsuccess/onerror 重复写很麻烦。封装时应支持版本升级、自动创建对象仓库,并返回 Promise。
- 检查是否已存在打开的连接,复用避免重复 open
- 在 upgradeneeded 回调中声明 objectStore 结构(仅首次或版本变更时执行)
- 成功时 resolve db 实例,失败时 reject 错误,便于上层统一 catch
封装增删改查:按操作语义暴露方法
每个 CRUD 操作都对应一个独立的 Promise 函数,不共用事务逻辑,降低耦合。
- add / put:传入数据和可选 key,自动使用当前默认事务(readwrite)
- get / getAll:支持主键查询、索引查询(如 index.get(key)),返回单条或数组
- delete:支持主键或范围删除(IDBKeyRange),失败时 reject 而非静默忽略
事务自动管理:避免手动 begin/commit
多数场景不需要显式控制事务生命周期。封装时可按需自动创建 read/write 事务,并在 Promise settle 后自动完成或中止。
- 读操作默认用 readonly 事务,写操作用 readwrite,减少权限冲突
- 同一事务内多个操作可链式调用(如先 add 再 get),共享 transaction
- 任意一步 reject,整个事务 abort,无需手动调用 transaction.abort()
错误处理与调试支持
原生错误信息模糊(如 "InvalidStateError"),封装层应增强可读性并提供上下文。
- 捕获常见错误码(如 AbortError、UnknownError),转为带操作类型和 store 名的提示
- 开发环境记录操作耗时、事务状态,方便排查性能瓶颈
- 支持传入自定义 onError 回调,便于集成 Sentry 或日志系统
封装不是为了完全屏蔽 IndexedDB,而是让开发者聚焦业务逻辑——打开、存取、报错,每一步都直白可控。