IndexedDB数据读取Promise未resolve问题:数据判断与网络获取异常
解决IndexedDB读取与Promise结合的问题
问题根源
resolve()无返回值:你把resolve(e.target.result)的返回值赋值给r,但resolve()本身就返回undefined,这是r始终为undefined的核心原因。- 异步流程混乱:直接在onsuccess回调里操作全局变量,没有遵循Promise的异步逻辑,导致结果处理时机错误。
- 未正确处理异步操作:
network_ip是async函数,但调用时没有await,且内部的IndexedDB操作未用Promise包装,无法确保存储完成后再执行后续逻辑。
修正后的代码及说明
首先把IndexedDB的操作Promise化,方便用async/await管理异步流程:
// 封装IndexedDB读取操作为Promise function getFromDB(db, storeName, key) { return new Promise((resolve, reject) => { // 读取操作只用readonly事务即可,没必要用readwrite const transaction = db.transaction(storeName, 'readonly'); const store = transaction.objectStore(storeName); const request = store.get(key); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } // 封装网络获取并存储IP的逻辑,确保异步操作完成 async function network_ip(db) { // 获取IP地址 const ipResponse = await fetch('https://example.com/ip.php'); const ipaddr = await ipResponse.text(); // 生成当前时间(应该在获取IP时生成,而不是提前定义) const currentTime = new Date().getTime(); return new Promise((resolve, reject) => { const transaction = db.transaction(['ip'], 'readwrite'); const store = transaction.objectStore('ip'); const request = store.put({ ip: ipaddr, times: currentTime }, 1); request.onsuccess = () => resolve({ ip: ipaddr, times: currentTime }); request.onerror = () => reject(request.error); }); } // 主逻辑:读取本地数据,不存在则拉取网络数据 async function initIP() { // 假设db是已经打开的IndexedDB实例 const storedData = await getFromDB(db, 'ip', 1); if (storedData && storedData.ip !== undefined && storedData.times !== undefined) { // 本地数据有效,直接使用 const { times: t, ip: i } = storedData; console.log('使用本地缓存数据:', t, i); return storedData; } else { // 本地无有效数据,拉取并存储新数据 const newData = await network_ip(db); console.log('使用新获取的数据:', newData); return newData; } } // 执行逻辑并处理错误 initIP().catch(error => console.error('IP处理出错:', error));
关键改动点
- 不再用
resolve()的返回值赋值变量,而是先获取IndexedDB的查询结果,判断后再处理。 - 把IndexedDB操作封装成Promise,用async/await替代回调嵌套,异步流程更清晰。
network_ip内部的时间戳在获取IP时生成,保证时间准确性;同时用Promise包装存储操作,确保存储完成后再返回结果。- 避免直接操作全局变量,通过函数返回值传递数据,符合现代异步编程规范。
内容的提问来源于stack exchange,提问作者redevil
相关产品推荐
相关产品推荐

