Html 正在访问ServiceWorker中的indexedDB。竞赛条件
在ServiceWorker中演示indexedDB的示例还不多,但我看到的示例都是这样构造的:Html 正在访问ServiceWorker中的indexedDB。竞赛条件,html,indexeddb,service-worker,Html,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 re
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的可靠方法是什么?我不知道通过控制页面访问indexedDB从服务工作者上下文访问indexedDB有什么特别之处 承诺显然会让您在服务人员中的生活变得更加轻松,因此我发现使用类似(例如)的东西来代替原始的IndexedDB API是有用的。但只要您创建并管理自己的承诺以反映异步IndexedDB操作的状态,就不必强制执行 在编写
fetch
事件处理程序时,需要记住的主要一点是(这并不特定于使用IndexedDB),如果调用event.respondWith()
,则需要传入响应
对象或使用响应
对象解析的承诺。只要您这样做,您的响应是从IndexedDB条目还是缓存API或其他地方构建的都不重要
您发布的代码是否遇到了实际问题,或者这更像是一个理论问题?您可以将交易包装成这样的承诺:
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.waitill()
等
正如其他评论所指出的,我们确实需要承诺IndexedDB。但其任务后自动提交模型的组成和承诺使用的微任务队列使其。。。在不完全替换API的情况下这样做是非常重要的。但是(作为一个实现者和规范编辑器之一),我正在积极地原型化一些想法。每次ServiceWorker启动时打开IDB不太可能是最佳的,即使没有使用它,您也会最终打开它。相反,在需要时打开数据库。单例在这里非常有用(请参阅),因此如果IDB在其生命周期中使用了两次,则无需再打开两次
“激活”事件是打开IDB并让任何“OnUpdate所需”事件运行的好地方,因为旧版本的ServiceWorker已经过时了。。代码运行良好,但这只是因为onsuccess事件总是“赢”。Promisify indexedDB可能是正确的解决方案。如果您不使用事务,只使用indexedDB(如localStorage),类似于我所链接的要点似乎效果很好。没错,但是它确实限制了IndexedDB的应用程序——你失去了将操作分组到原子事务中的能力,而且当所有操作都在自己的事务中时,它的速度非常慢。是的。但是如果您在软件中使用它,您可能没有更好的选择。在这些限制条件下,它仍然可以被证明是有用的。您应该能够在fetch处理程序中打开IDB连接,只要您将该操作包装在承诺中,然后将其用作传递给event.respondWith()的承诺链的一部分值得检查以下反映indexedDb的小型库:您好,来自未来!链接的(“承诺的”)库在NPM上看起来并不流行,我也没有看到规范的任何变化。作为一个在承诺规范稳定的时候就开始认真开发JS的人,我在阅读IDB规范时的第一个想法是“他们不可能是认真的”。这个API的官方现代版本(基于回调/基于承诺,而不是基于事件处理程序)有什么进展吗?