IndexedDB 使用键获取所有数据

IndexedDB getting all data with keys

使用 IndexedDB API 我们有这两种方法:getAll()getAllKeys() 下面是一个用法示例:

let transaction = this.db.transaction(["table"]);
let object_store = transaction.objectStore("table");
request = object_store.getAll(); /* or getAllKeys() */

request.onerror = (event) => {
    console.err("error fetching data");
};
request.onsuccess = (event) => {
    console.log(request.result);
};

问题是 getAll() 似乎只检索数组格式的数据,而 getAllKeys() 获取所有键而没有数据。我找不到同时获取键和值的方法。

  1. 有没有更好的方法来一次调用获取数据密钥,就像它被存储一样?

  2. 如果没有,有没有更好的方法可以做到这一点,而不会使代码与发生的多个异步调用混淆?

我能够使用一个回调函数检索所有值及其键,使用 IDBCursor 像这样:

transaction = this.db.transaction(["table"]);
object_store = transaction.objectStore("table");
request = object_store.openCursor();

request.onerror = function(event) {
   console.err("error fetching data");
};
request.onsuccess = function(event) {
   let cursor = event.target.result;
   if (cursor) {
       let key = cursor.primaryKey;
       let value = cursor.value;
       console.log(key, value);
       cursor.continue();
   }
   else {
       // no more results
   }
};

或者,您可以使用 getAllKeys,然后使用事务来获取每个键的值。

const getAll = (db, store) => new Promise((res, rej) => {
  // Fetch keys
  const keysTr = db.transaction(store).objectStore(store).getAllKeys()
  keysTr.onsuccess = (event) => {
    const keys = event.target.result
    if (keys?.length) {
      // Start a new transaction for final result
      const valuesTr = db.transaction(store)
      const objStore = valuesTr.objectStore(store)

      const result = [] // { key, value }[]

      // Iterate over keys
      keys.forEach(key => {
        const tr = objStore.get(key)
        tr.onsuccess = e => {
          result.push({
            key,
            value: e.target.result
          })
        }
      })
      // Resolve `getAll` with final { key, value }[] result
      valuesTr.oncomplete = (event) => {
        res(result)
      }
      valuesTr.onerror = (event) => {
        rej(event)
      }
    }
    else
      res([])
  }
  keysTr.onerror = (event) => {
    rej(event)
  }
})