2017-03-19 107 views
3

有许多例子在那里初始化服务工作者类似于下面的一个缓存:服务工作者与多个缓存

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(); 
}); 

这种做法似乎工作。不过,我仍然是服务工作者和承诺的新手。有些东西告诉我,这种方法有一个缺陷,即我经验不足以承认。有没有更好的方法来实现这一点?

回答

4

最好只在处理程序中调用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只在阵列的决心,这意味着install处理程序将等到所有缓存被初始化所有承诺后,需要承诺的阵列和解决。

2

谢谢pirxpilot!你的回答,加上JavaScript Promises: an Introduction,以及大量的试验和错误,弄清楚如何将所有这些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) { 
     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); 
     } 
     })); 
    }) 
); 
});