网络工作者中的 Dexie 承诺永远不会解决/拒绝

问题描述 投票:0回答:0

[已解决:见底部更新]

我在 Web Worker 中遇到了 Dexie 的奇怪问题。我不知道这个问题是由 Dexie 引起的,是 IndexedDB 的问题,还是与我使用 Dexie 的方式有关。

这是一个工作正常的场景:

  • 应用程序启动,通过 websocket 向服务器发送请求。
  • 服务器通过websocket响应数据;数据被发送到 web workers,运行各种功能,运行 Dexie 查询,更新 Dexie 数据库等,然后通过
    postMessage
    .
  • 将数据发送回主 UI 线程

这是另一个运行良好的稍微不同的场景:

  • 当应用程序运行时,用户交互(例如,点击某物),导致请求通过 websocket 发送到服务器。
  • 服务器通过websocket响应数据;数据被发送到 web workers,运行各种功能,运行 Dexie 查询,更新 Dexie 数据库等,然后通过
    postMessage
    .
  • 将数据发送回主 UI 线程

这是一个不起作用的场景:

  • 当应用程序运行时,用户交互(例如,点击某物),导致数据直接发送到网络工作者。 Web Worker 开始运行 Dexie 查询,但它遇到的第一个承诺挂起,既没有解决也没有拒绝。没有任何反应,应用程序卡住了。

换句话说,只要有到服务器的往返,一切都正常,但是直接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
事件给我带来的麻烦已经不是第一次了

indexeddb web-worker dexie
© www.soinside.com 2019 - 2024. All rights reserved.