Vue3使用idb库操作IndexedDB时遭遇DOMException错误求助
问题排查与修复
主要错误原因
- 无限递归触发异常:你自定义的
openDB函数里,错误地调用了自身(await openDB('test')),而不是idb库提供的openDB方法,这会直接导致栈溢出,抛出你看到的DOMException。 - 缺失数据库初始化逻辑:使用idb打开数据库时,必须指定版本号,且首次创建时需要通过
upgrade回调定义对象仓库,之前的代码缺少这部分,也会导致数据库初始化失败。
修正后的完整代码
TypeScript模块代码
// 导入idb库的openDB方法并重命名,避免和自定义函数冲突 import { openDB as idbOpenDB } from 'idb' let dbInstance: any const openDB = async () => { try { if (!dbInstance) { // 调用idb库的openDB方法,传入数据库名、版本号和初始化逻辑 dbInstance = await idbOpenDB('test', 1, { upgrade(db) { // 检查并创建对象仓库A和B if (!db.objectStoreNames.contains('A')) { db.createObjectStore('A') } if (!db.objectStoreNames.contains('B')) { db.createObjectStore('B') } }, }) } return dbInstance } catch (e: any) { console.error('数据库打开失败:', e) } } const getDataA = async () => { const db = await openDB() // 显式指定只读事务模式,代码更清晰且符合规范 const store = db.transaction('A', 'readonly').objectStore('A') return await store.getAll() } const getDataB = async () => { const db = await openDB() const store = db.transaction('B', 'readonly').objectStore('B') return await store.getAll() }
组件调用代码(无需修改)
const [dataA, dataB] = await Promise.all([ getDataA(), getDataB(), ])
补充说明
- 事务模式:虽然IndexedDB默认事务是只读的,但显式声明
'readonly'能让代码意图更明确,后续如果需要写操作,直接改成'readwrite'即可。 - 单例复用:你的
dbInstance单例逻辑是正确的,避免重复打开数据库连接,提升性能。
内容的提问来源于stack exchange,提问作者Nguyen Duc Kien
相关产品推荐
相关产品推荐

