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

PWA中Ajax请求失败时如何访问IndexedDB缓存数据?

处理PWA离线缓存与在线更新的正确姿势

你的思路完全没问题:在线时优先用接口数据并同步更新本地缓存,离线时 fallback 到IndexedDB里的缓存数据。但现有代码里有个核心问题需要修正——异步操作的处理逻辑,因为IndexedDB的读写都是异步的,不能像同步代码那样直接赋值res,否则拿到的会是Promise对象而非实际数据。

先明确两个工具函数的异步特性

首先假设你的getCacheAudits和getServerAudits都是返回Promise的异步函数(如果还不是,建议改成这样,IndexedDB操作一定要用Promise封装,避免回调嵌套的混乱):

  • getCacheAudits(start, end):查询IndexedDB中指定时间范围的审计数据,resolve返回数据(空数组或有效数据)
  • getServerAudits(audits):将接口返回的审计数据存入IndexedDB,resolve表示缓存写入成功

修正后的getAudits函数

我用async/await重构了代码,让异步逻辑更清晰易懂:

getAudits: async (startOfMonth, endOfMonth) => {
  try {
    // 发起在线请求
    const response = await request
      .get(`${url}api/?method=Audit.data`)
      .query({
        pageLength: "all",
        format: "json",
        where: startOfMonth 
          ? Utils.hashQuery("a.date", "between", [startOfMonth, endOfMonth].toString())
          : "",
        ts: new Date().getTime()
      });

    // 解析接口返回的数据
    const auditRows = JSON.parse(response.text).rows;
    const audits = Utils.toArray(auditRows); // 如果rows本身是数组,可直接用auditRows替代

    // 等待缓存更新完成(确保下次离线能拿到最新数据)
    await getServerAudits(audits);

    // 返回接口的最新数据
    return audits;
  } catch (networkError) {
    // 网络请求失败,尝试读取本地缓存
    try {
      const cachedAudits = await getCacheAudits(startOfMonth, endOfMonth);
      // 缓存有数据就返回,无数据则返回空数组(可根据业务需求调整)
      return cachedAudits.length ? cachedAudits : [];
    } catch (cacheError) {
      // 缓存读取也失败时,才抛出最终错误
      throw new Error(`网络请求失败且缓存读取失败: ${cacheError.message}`);
    }
  }
}

关键修改点说明

  1. 改用async/await:替代原来的Promise回调嵌套,代码可读性大幅提升,异步流程更直观。
  2. 正确处理异步缓存操作:
    • 在线成功时,用await等待getServerAudits完成,确保缓存更新后再返回数据,避免下次离线时拿到旧缓存。
    • 离线时,用await获取getCacheAudits的实际结果,而不是直接赋值(原来的写法会拿到Promise对象,不是真实数据)。
  3. 分层错误处理:先捕获网络请求错误,再尝试读取缓存;只有当缓存也读取失败时,才抛出最终错误,避免前端直接无数据可用。
  4. 简化数据解析:如果接口返回的rows本身就是数组,Utils.toArray可以省略,直接用JSON.parse(response.text).rows即可。

额外优化建议

  • 缓存时间戳:可以在缓存中存储数据的更新时间,下次在线时对比服务器数据的更新时间,避免重复缓存相同内容。
  • 缓存失效策略:设置缓存过期时间,超过时限后,即使在线也强制刷新数据,保证缓存时效性。
  • Service Worker配合:如果你的PWA使用了Service Worker,可以在请求拦截层面做离线缓存,和IndexedDB的缓存形成互补,进一步提升离线体验。

内容的提问来源于stack exchange,提问作者Rúben Santos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:52:46