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

如何在非async函数中等待IndexedDB Promise执行完成?

解决方案

问题的核心是你的dbGetProdData函数没有正确等待内部所有异步操作(IndexedDB读取、getDataByFetch调用)完成就提前resolve了Promise,导致then回调里的createSizeFilterOptions执行时机过早。你需要先修复dbGetProdData,让它返回的Promise在所有异步任务结束后才完成,调用方无需改成async/await也能正常等待。

步骤1:修复dbGetProdData函数

方式一:用Promise链式包装所有异步操作

如果你的getDataByFetch返回Promise,确保在IndexedDB读取完成后等待它执行完毕,再resolve外层Promise:

function dbGetProdData() {
  return new Promise((resolve, reject) => {
    // 打开IndexedDB
    const openRequest = indexedDB.open('你的数据库名');
    
    openRequest.onsuccess = (event) => {
      const db = event.target.result;
      // 开启事务并读取数据
      const tx = db.transaction('你的存储对象名', 'readonly');
      const store = tx.objectStore('你的存储对象名');
      const getRequest = store.getAll(); // 示例读取所有数据,根据你的需求调整
      
      getRequest.onsuccess = async () => {
        try {
          // 等待getDataByFetch异步操作完成
          await getDataByFetch();
          // 可以把读取到的IndexedDB数据传递出去,供后续使用
          resolve(getRequest.result);
        } catch (err) {
          reject(err);
        }
      };
      
      // 处理各环节的错误
      getRequest.onerror = (err) => reject(err);
      tx.onerror = (err) => reject(err);
    };
    
    openRequest.onerror = (err) => reject(err);
  });
}

方式二:用async/await改写(更简洁)

先把IndexedDB操作封装成Promise,再用async函数串联所有异步任务:

// 封装IndexedDB数据读取为独立的Promise函数
function fetchFromIndexedDB() {
  return new Promise((resolve, reject) => {
    const openRequest = indexedDB.open('你的数据库名');
    openRequest.onsuccess = (event) => {
      const db = event.target.result;
      const tx = db.transaction('你的存储对象名', 'readonly');
      const store = tx.objectStore('你的存储对象名');
      const getRequest = store.getAll();
      
      getRequest.onsuccess = () => resolve(getRequest.result);
      getRequest.onerror = (err) => reject(err);
      tx.onerror = (err) => reject(err);
    };
    openRequest.onerror = (err) => reject(err);
  });
}

// 改写dbGetProdData为async函数
async function dbGetProdData() {
  // 先等IndexedDB读取完成
  const prodData = await fetchFromIndexedDB();
  // 再等getDataByFetch完成
  await getDataByFetch();
  // 返回数据(可选,供后续回调使用)
  return prodData;
}

步骤2:保持原调用方式即可

修复后的dbGetProdData返回的Promise会等待所有异步操作完成,原调用代码无需改动,createSizeFilterOptions会在数据准备好后执行:

dbGetProdData().then((prodData) => {
  // 这里可以直接使用prodData(如果需要)
  createSizeFilterOptions();
}).catch((err) => {
  // 记得添加错误处理,避免静默失败
  console.error('获取产品数据失败:', err);
});

关键提醒:无论哪种方式,都要确保getDataByFetch本身返回Promise——如果它原本没有返回,你需要先改造它,把内部异步操作包装成Promise,否则await或链式调用无法等待它完成。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:25:37