[已解决:见底部更新]
我在 Web Worker 中遇到了 Dexie 的奇怪问题。我不知道这个问题是由 Dexie 引起的,是 IndexedDB 的问题,还是与我使用 Dexie 的方式有关。
这是一个工作正常的场景:
postMessage
.这是另一个运行良好的稍微不同的场景:
postMessage
.这是一个不起作用的场景:
换句话说,只要有到服务器的往返,一切都正常,但是直接UI线程->网络工作线程-> Dexie调用不起作用。
当我尝试直接访问 IndexedDB 而不是 Dexie 调用时,也会出现此问题:
try {
const req = self.indexedDB.open('dummyDb');
console.log('request', req); // this works; I can log the request object
req.onblocked = (evt) => {
console.error('blocked', evt); // this is never called
};
req.onerror = (evt) => {
console.error('error', evt); // this is never called
};
req.onsuccess = (evt) => {
console.log('success', evt, req.result); // this is never called
};
} catch (e) {
onerror(e); // this is never called
}
因此,肯定是 IndexedDB 挂了,但为什么呢?它的行为就像一个死锁事务,但我已经从代码中删除了所有(显式)事务,它仍然发生。我不使用
Collection.each()
,也不知道有没有其他Dexie函数使用隐式交易
我无法在一个只有两个网络工作者的简单应用程序中重现该问题,一个写入数据库,另一个从同一个数据库读取。所以我不知道如何继续诊断问题。
更新
好吧,原来这是一条红鲱鱼。实际发生的是 web worker 在代码的其他地方被无意中终止,但还没有被 GC。然而,即使在那种僵尸状态下,它也能够接受消息并工作。但是一旦它遇到第一个等待,它的线程将永远保持未调度状态。
Web worker 中缺少
onclose
或onterminate
事件给我带来的麻烦已经不是第一次了