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

IndexedDB数据读取Promise未resolve问题:数据判断与网络获取异常

解决IndexedDB读取与Promise结合的问题

问题根源

  1. resolve()无返回值:你把resolve(e.target.result)的返回值赋值给r,但resolve()本身就返回undefined,这是r始终为undefined的核心原因。
  2. 异步流程混乱:直接在onsuccess回调里操作全局变量,没有遵循Promise的异步逻辑,导致结果处理时机错误。
  3. 未正确处理异步操作: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:40:33