10

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

4

3 回答 3

11

每次 ServiceWorker 启动时都打开 IDB 不太可能是最优的,即使不使用它,您最终也会打开它。相反,在需要时打开数据库。单例在这里非常有用(请参阅https://github.com/jakearchibald/svgomg/blob/master/src/js/utils/storage.js#L5),因此如果使用它,您不需要打开 IDB 两次在其一生中两次。

“activate”事件是打开 IDB 并让任何“onupdateneeded”事件运行的好地方,因为旧版本的 ServiceWorker 已经不存在了。

于 2015-03-25T16:24:08.083 回答
11

你可以像这样在一个 Promise 中包装一个事务:

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()ore.waitUntil()等​​。

正如其他评论者所指出的,我们确实需要承诺 IndexedDB。但是它的 post-task 自动提交模型和 Promises 使用的微任务队列的组合使得它......在不完全替换 API 的情况下这样做并不简单。但是(作为实施者和规范编辑之一)我正在积极地对一些想法进行原型设计。

于 2015-03-24T16:07:41.690 回答
4

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

Promise 显然让你在 service worker 中的生活更轻松,所以我发现使用类似https://gist.github.com/inexorabletash/c8069c042b734519680c的东西来代替原始的 IndexedDB API 是有用的。但这不是强制性的,只要您创建和管理自己的 Promise 以反映异步 IndexedDB 操作的状态。

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

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

于 2015-03-23T20:49:31.923 回答