You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery调用async/await实现IndexedDB创建失败,如何正确处理及检测库存在

问题核心原因

IndexedDB原生API为回调设计,未直接适配Promise,仅给函数添加async关键字无法自动等待异步回调执行完成,你现有代码存在两个明确错误:

  • createDb函数中,onsuccess回调里的return仅作用于回调函数本身,外层async函数没有等待回调触发就执行结束,所以await拿到的结果始终为undefined
  • dbExists函数的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 23:18:03