如何在 Onupgradeneeded 触发时等待 IndexedDB 打开

How to Await an IndexedDB Open when Onupgradeneeded Fires

我刚开始学习 Web 开发和 IndexedDB。我已经成功地使用 Visual Studio 创建了一个测试 Blazor WebAssembly 应用程序并合并了一个 IndexedDB。特别是,我已经成功地创建了数据库,用数据填充了一个存储区,并随后检索了该数据。到目前为止,一切都很好。作为其中的一部分,我已经能够在我的 JavaScript 代码中自动打开数据库,一旦打开就读取数据存储,并使用 JSON 将数据传递给 Blazor c# 方法,这样我就可以通过现有的 c# 代码处理它。我已经能够通过在打开的数据库上使用 "await" 来使后者工作,从而确保它在后续代码尝试检索数据之前打开。花了很长时间才将所有这些拼凑在一起,但它确实有效。但是当我更改数据库版本时它不起作用,从而触发onupgradeneeded事件。在那种情况下,等待似乎不起作用,因为尝试读取数据的 js 在 Open 完成之前正在执行。所以,我希望了解我做错了什么或没做什么。

谢谢。史蒂夫

async function Database_Open()
{
    var dbReq = await indexedDB.open(databaseName, 1);
    dbReq.onupgradeneeded = function (event) 
    {
        meDatabase = (event.target as any).result;

        let bbDetailStore = meDatabase.createObjectStore(bbDetailStoreName, { autoIncrement: true });
        console.log(bbDetailStore.keyPath);
        bbDetailStore.createIndex("by_VblName", "vblName", { unique: false });
        bbDetailStore.createIndex("by_Year", "year", { unique: false });
    }
    dbReq.onsuccess = function (event) { meDatabase = (<IDBOpenDBRequest>event.target).result; let x = 1; }
    dbReq.onerror = function (event) { alert('error opening database ' + (event.target as any).errorCode); }
}

使用传统的 Promise 语法可能比 async/await 更幸运。它们对于 "Promisifying" 一些基于回调 and/or 事件的东西不是很有用,比如 indexedDB.

function Database_Open()
{
    return new Promise(function(resolve, reject) {
      var dbReq = indexedDB.open(databaseName, 1);
      dbReq.onupgradeneeded = function (event) 
      {
          meDatabase = (event.target as any).result;

          let bbDetailStore = meDatabase.createObjectStore(bbDetailStoreName, { autoIncrement: true });
          console.log(bbDetailStore.keyPath);
          bbDetailStore.createIndex("by_VblName", "vblName", { unique: false });
          bbDetailStore.createIndex("by_Year", "year", { unique: false });
          resolve(dbReq);
      }
      dbReq.onsuccess = function (event) { 
        meDatabase = (<IDBOpenDBRequest>event.target).result; 
        let x = 1;
        resolve(dbReq);
      }
      dbReq.onerror = function (event) {
        reject('error opening database ' + (event.target as any).errorCode);
      }
    });
}

另外值得注意的是,已经有非常好的资源可用于承诺 indexedDB,包括不知疲倦的 Jake Archibald 的 idb, and others available on npm

通常对于生产代码,您最好使用这样的解决方案,因为它可能经过了更多实战测试。