jQuery调用async/await实现IndexedDB创建失败,如何正确处理及检测库存在
问题核心原因
IndexedDB原生API为回调设计,未直接适配Promise,仅给函数添加async关键字无法自动等待异步回调执行完成,你现有代码存在两个明确错误:
createDb函数中,onsuccess回调里的return仅作用于回调函数本身,外层async函数没有等待回调触发就执行结束,所以await拿到的结果始终为undefineddbExists函数的return是同步执行的,onupgradeneeded为异步触发的回调,return执行时回调还未运行,返回值永远是初始的true
正确实现方案
1. 封装适配Promise的工具函数
// 数据库存在检测异步版 async function dbExists(dbName) { return new Promise((resolve, reject) => { const request = indexedDB.open(dbName); let existed = true; request.onupgradeneeded = (e) => { // 触发upgradeneeded说明数据库不存在,属于首次创建场景 e.target.transaction.abort(); existed = false; }; request.onsuccess = () => { // 关闭临时打开的连接,避免资源占用 request.result.close(); resolve(existed); }; request.onerror = (e) => reject(e.target.error); }); } // 数据库创建/打开异步版 async function createDb(dbName, version = 1) { return new Promise((resolve, reject) => { // 注意版本号必须为正整数,不能传字符串格式 const request = indexedDB.open(dbName, version); request.onsuccess = () => resolve(request.result); request.onerror = (e) => reject(e.target.error); // 可在此处添加onupgradeneeded逻辑,完成表、索引的初始化创建 request.onupgradeneeded = (e) => { const db = e.target.result; // 示例:创建用户表,实际按你的业务需求修改 if (!db.objectStoreNames.contains('users')) { db.createObjectStore('users', { keyPath: 'id', autoIncrement: true }); } }; }); }
2. 组合检测+创建逻辑
async function initDatabase() { try { const isDbExisted = await dbExists('myDB'); let dbInstance; if (isDbExisted) { console.log('数据库已存在,直接打开连接'); dbInstance = await createDb('myDB', 1); } else { console.log('数据库不存在,执行初始化创建'); dbInstance = await createDb('myDB', 1); } console.log('数据库实例获取成功:', dbInstance); // 后续业务逻辑可直接使用dbInstance操作数据库 return dbInstance; } catch (err) { console.error('数据库初始化失败:', err); throw err; } } // 在DOM加载完成后调用 document.addEventListener('DOMContentLoaded', async () => { await initDatabase(); });
注意事项
- IndexedDB的版本号必须为正整数,不能传入字符串类型,否则会触发隐式转换导致未知异常
- 数据库实例使用完毕后,若不需要长期持有连接,可调用
db.close()主动关闭释放资源 - 所有异步操作建议添加try/catch捕获错误,避免数据库操作失败导致页面逻辑中断
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

