簡體   English   中英

具有多個緩存的服務工作者

[英]Service Worker with Multiple Caches

有許多示例用於使用類似於以下內容的單個緩存初始化服務工作者:

let cacheName = 'myCacheName-v1';
let urlsToCache = ['url1', 'url2', url3'];

self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open(cacheName).then(function (cache) {
      return cache.addAll(urlsToCache);
    }).then(function () {
      return this.skipWaiting();
    })
  );
});

我希望在我的服務工作者上初始化多個緩存。 動機是根據變化趨勢對資產進行分組(例如,靜態應用數據與css,javascript等)。 使用多個緩存,我可以將單個緩存(通過版本化緩存名稱)更新為緩存更改中的文件。 理想情況下,我希望設置類似於以下的結構:

let appCaches = [{
    name: 'core-00001',
    urls: [
      './',
      './index.html', etc...
    ]
  },
  {
    name: 'data-00001',
    urls: [
      './data1.json',
      './data2.json', etc...
    ]
  },
  etc...
];

到目前為止,我最好的嘗試類似於:

self.addEventListener('install', function (event) {
  appCaches.forEach(function (appCache) {
    event.waitUntil(
      caches.open(appCache.name).then(function (cache) {
        return cache.addAll(appCache.urls);
      }));
  });
  self.skipWaiting();
});

這種方法似乎有效。 但是,我仍然是服務工人和承諾的新手。 有些東西告訴我,這種方法有一個陷阱,我太缺乏經驗,無法識別。 有沒有更好的方法來實現這個?

最好在處理程序中調用event.waitUntil一次,但好處是讓單個Promise等待相對容易。

這樣的東西應該工作:

event.waitUntil(Promise.all(
  myCaches.map(function (myCache) {
    return caches.open(myCache.name).then(function (cache) {
      return cache.addAll(myCache.urls);
    })
  )
));

Promise.all接受一個Promise.all數組,只有在Array中的所有promise都解析后才會解析,這意味着install處理程序將等到所有緩存都被初始化。

謝謝pirxpilot 你的答案,結合JavaScript Promises:一個簡介 ,以及如何將所有這些Promise鏈接在一起的大量試驗和錯誤導致了一個很好的小實現。

我添加了一個僅緩存更改的要求。 根據最佳實踐,在“激活”事件期間刪​​除舊緩存。 最終產品是:

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

self.addEventListener('install', function (event) {
  event.waitUntil(caches.keys().then(function (keys) {
    return Promise.all(appCaches.map(function (appCache) {
      if (keys.indexOf(appCache.name) === -1) {
        return caches.open(appCache.name).then(function (cache) {
          console.log(`caching ${appCache.name}`);
          return cache.addAll(appCache.urls);
        })
      } else {
        console.log(`found ${appCache.name}`);
        return Promise.resolve(true);
      }
    })).then(function () {
      return this.skipWaiting();
    });
  }));
});

self.addEventListener('activate', function (event) {
  event.waitUntil(
    caches.keys().then(function (keys) {
      return Promise.all(keys.map(function (key) {
        if (cacheNames.indexOf(key) === -1) {
          console.log(`deleting ${key}`);
          return caches.delete(key);
        }
      }));
    })
  );
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM