在ServiceWorker中访问indexedDB。比赛条件

时间:2015-03-23 09:30:28

标签: html5 indexeddb service-worker

在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的有效方法是什么?

3 个答案:

答案 0 :(得分:11)

您可以将事务包装在这样的承诺中:

var tx = db.transaction(scope, mode);
var p = new Promise(function(resolve, reject) {
  tx.onabort = function() { reject(tx.error); };
  tx.oncomplete = function() { resolve(); };
});

现在p将在事务完成/中止时解析/拒绝。因此,您可以在tx交易和p.then(...)中执行任意逻辑和/或将相关承诺传递到e.respondWith()e.waitUntil()等。

正如其他评论者所指出的,我们确实需要宣传IndexedDB。但是它的任务后自动提交模型的组成和Promises使用的微任务队列使得...在没有基本上完全替换API的情况下这样做是非常重要的。但是(作为实施者和规范编辑之一)我正在积极地为一些想法做原型。

答案 1 :(得分:8)

每次ServiceWorker启动时打开IDB都不太可能是最佳的,即使没有使用它也会打开它。而是在需要时打开数据库。单身人士在这里非常有用(参见https://github.com/jakearchibald/svgomg/blob/master/src/js/utils/storage.js#L5),因此如果在生命周期内使用过两次,你就不需要再开两次。

"激活"活动是开放IDB的好地方,让任何" onupdateneeded"事件运行,因为旧版本的ServiceWorker已经不在了。

答案 2 :(得分:4)

我不知道通过受控页面访问IndexedDB从服务工作者的上下文访问IndexedDB有什么特别之处。

Promise显然会让服务工作者的生活变得更轻松,所以我发现使用像https://gist.github.com/inexorabletash/c8069c042b734519680c这样的东西来代替原始的IndexedDB API。但只要您创建和管理自己的promise以反映异步IndexedDB操作的状态,它就不是强制性的。

编写fetch事件处理程序时要记住的主要事项(这不是特定于使用IndexedDB),如果您调用event.respondWith(),则需要传入Response对象或使用Response对象解析的promise。只要你这样做,你的Response是从IndexedDB条目还是Cache API或其他地方构建的都无关紧要。

您是否遇到了所发布代码的任何实际问题,或者这更像是一个理论问题?