【问题标题】:Service Worker Detect Cache CompletedService Worker 检测缓存完成
【发布时间】:2022-02-16 00:22:11
【问题描述】:

我的 PWA 的数据负载很大。我想显示一个“请稍候...”加载页面并等到所有缓存完成后再启动完整的应用程序。因此,我需要检测所有缓存何时完成。我的 service worker 的 sn-p 是:

let appCaches = [{
    name: 'pageload-core-2018-02-14.002',
    urls: [
      './',
      './index.html',
      './manifest.json',
      './sw.js',
      './sw-register.js'
    ]
  },
  {
    name: 'pageload-icon-2018-02-14.002',
    urls: [
      './icon-32.png',
      './icon-192.png',
      './icon-512.png'
    ]
  },
  {
    name: 'pageload-data-2019-02-14.002',
    urls: [
      './kjv.js'
    ]
  }
];

let cacheNames = appCaches.map((cache) => cache.name);

self.addEventListener('install', function (event) {
  console.log('install');
  event.waitUntil(caches.keys().then(function (keys) {
    return Promise.all(appCaches.map(function (appCache) {
      if (keys.indexOf(appCache.name) === -1) {
        caches.open(appCache.name).then(function (cache) {
          return cache.addAll(appCache.urls).then(function () {
            console.log(`Cached: ${appCache.name} @ ${Math.floor(Date.now() / 1000)}`);
          });
        });
      } else {
        console.log(`Found: ${appCache.name}`);
        return Promise.resolve(true);
      }
    })).then(function () {
      // Happens first; expected last.
      console.log(`Cache Complete @ ${Math.floor(Date.now() / 1000)}`);
    });
  }));
  self.skipWaiting();
});

当我使用模拟的 3G 网络进行测试时,轨迹是:

我不明白为什么在记录任何单独的“缓存”消息之前会记录“缓存完成”消息;我希望它是最后一个。与其他 Promise 相比,Promise.all 的行为方式有什么不同吗?

【问题讨论】:

    标签: javascript service-worker progressive-web-apps


    【解决方案1】:

    喂!多么愚蠢的疏忽。在将 Promise 链分解成单独的 Promise 并单步执行代码后,问题变得很明显。

    self.addEventListener('install', function (event) {
      console.log('install');
      event.waitUntil(caches.keys().then(function (keys) {
        return Promise.all(appCaches.map(function (appCache) {
          if (keys.indexOf(appCache.name) === -1) {
            // Never returned the promise chain to map!!!
            return caches.open(appCache.name).then(function (cache) {
              return cache.addAll(appCache.urls).then(function () {
                console.log(`Cached: ${appCache.name} @ ${Math.floor(Date.now() / 1000)}`);
              });
            });
          } else {
            console.log(`Found: ${appCache.name}`);
            return Promise.resolve(true);
          }
        })).then(function () {
          console.log(`Cache Complete @ ${Math.floor(Date.now() / 1000)}`);
        });
      }));
      self.skipWaiting();
    });
    

    我从未将承诺链返回给map 函数(没有明确的return 总是返回undefined)。所以传递给Promise.all 的数组只包含undefined 值。因此,它立即解决并因此在其他人之前记录了它的消息。

    生活和学习...

    【讨论】:

      【解决方案2】:

      @claytoncarney 你知道如何通过回调.. 或任何方式从我的应用程序中收听此事件吗?

      我尝试向我的用户发送一条 toast 消息,告诉他们数据已被缓存...

      在这种情况下,我发送警报(它不起作用)...

      【讨论】:

      • 最好是输入您的代码而不是发布它的图像。对于某些人来说,图像可能难以阅读。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      • 2018-05-14
      • 1970-01-01
      • 2019-10-08
      • 2020-02-10
      • 2018-02-19
      • 1970-01-01
      相关资源
      最近更新 更多