在ServiceWorker中展示indexedDB的示例并不多,但我看到的结构都是这样的:
const request = indexedDB.open( 'myDB',1 ); var db; request.onupgradeneeded = ... request.onsuccess = function() { db = this.result; // Average 8ms }; self.onfetch = function(e) { const requestURL = new URL( e.request.url ),path = requestURL.pathname; if( path === '/test' ) { const response = new Promise( function( resolve ) { console.log( performance.now(),typeof db ); // Average 15ms db.transaction( 'cache' ).objectStore( 'cache' ).get( 'test' ).onsuccess = function() { resolve( new Response( this.result,{ headers: { 'content-type':'text/plain' } } ) ); } }); e.respondWith( response ); } }
ServiceWorker启动时可能会失败,如果是这样,在ServiceWorker中访问indexedDB的有效方法是什么?
解决方法
每次ServiceWorker启动时打开IDB都不太可能是最佳的,即使不使用它也会打开它.而是在需要时打开数据库.单例在这里非常有用(参见
https://github.com/jakearchibald/svgomg/blob/master/src/js/utils/storage.js#L5),因此如果它在其生命周期中使用了两次,则不需要打开IDB两次.
“激活”事件是打开IDB并允许任何“onupdateneeded”事件运行的好地方,因为旧版本的ServiceWorker已经不在了.