如何在非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
相关产品推荐
相关产品推荐

