【问题标题】:Can't save values using indexedDB无法使用 indexedDB 保存值
【发布时间】:2021-06-08 06:48:36
【问题描述】:

你好,我被 indexedDB 困住了。当我尝试存储链接数组时,它会失败,没有错误或异常。 我有两个代码示例。这个工作正常:

export const IndexedDB = {
  initDB(): Promise<string> {
    return new Promise((resolve, reject) => {
      const open = indexedDB.open("MyDB", 1);
      open.onupgradeneeded = function () {
        open.result.createObjectStore("store", { keyPath: "id" });
        resolve("Database initialized successfully...");
      };
      open.onerror = function (err) {
        reject(err);
      };
      open.onsuccess = function () {
        resolve("Database initialized successfully...");
      };
    });
  },

  getAll(): Promise<Values> {
    return new Promise((resolve, reject) => {
      const open = indexedDB.open("MyDB", 1);
      open.onerror = function (err) {
        reject(err);
      };

      open.onsuccess = function () {
        const tx = open.result.transaction("store", "readonly");
        const store = tx.objectStore("store");
        const getFromStore = store.getAll();

        getFromStore.onerror = function (err) {
          reject(err);
        };

        getFromStore.onsuccess = function () {
          resolve(getFromStore.result);
        };
      };
    });
  },

  putMany(values: Values): Promise<void> {
    return new Promise((resolve, reject) => {
      const open = indexedDB.open("MyDB", 1);
      open.onerror = function (err) {
        reject(err);
      };

      open.onsuccess = function () {
        values.forEach((value: Value) => {
          const tx = open.result.transaction("store", "readwrite");
          const store = tx.objectStore("store");
          const putInStore = store.put(value);

          putInStore.onerror = function (err) {
            reject(err);
          };
        });
        resolve();
      };
    });
  },
};

App.tsx:

export const saveValues = (values: Values): Promise<void> => {
  IndexedDB.putMany(values);
};

export const App: React.FunctionComponent = () => {
  const valuesForTest: Values = [
    {
      id: Math.random(),
      text: "Hello world!"
    },
    {
      id: Math.random(),
      text: "Hello world!"
    },
    {
      id: Math.random(),
      text: "Hello world!"
    }
  ];

  useEffect(() => {
        saveValuesToDB(valuesForTest);
  }, []);

  return (
    <SomeComponent/>
  );
};

而这个总是失败。完全没有错误或异常。只是没有保存数据。 主要区别只是数据类型。第一个示例使用“Values”类型,第二个示例使用“Links”类型。

export const IndexedDB = {
  initDB(): Promise<string> {
    return new Promise((resolve, reject) => {
      const open = indexedDB.open("MyDB", 1);
      open.onupgradeneeded = function () {
        open.result.createObjectStore("store", { keyPath: "href" });
        resolve("Database initialized successfully...");
      };
      open.onerror = function (err) {
        reject(err);
      };
      open.onsuccess = function () {
        resolve("Database initialized successfully...");
      };
    });
  },

  getAll(): Promise<Links> {
    return new Promise((resolve, reject) => {
      const open = indexedDB.open("MyDB", 1);
      open.onerror = function (err) {
        reject(err);
      };

      open.onsuccess = function () {
        const tx = open.result.transaction("store", "readonly");
        const store = tx.objectStore("store");
        const getFromStore = store.getAll();

        getFromStore.onerror = function (err) {
          reject(err);
        };

        getFromStore.onsuccess = function () {
          resolve(getFromStore.result);
        };
      };
    });
  },

  putMany(values: Links): Promise<void> {
    return new Promise((resolve, reject) => {
      const open = indexedDB.open("MyDB", 1);
      open.onerror = function (err) {
        reject(err);
      };

      open.onsuccess = function () {
        values.forEach((value: Link) => {
          const tx = open.result.transaction("store", "readwrite");
          const store = tx.objectStore("store");
          const putInStore = store.put(value);

          putInStore.onerror = function (err) {
            reject(err);
          };
        });
        resolve();
      };
    });
  },
};

App.tsx:

export const saveValues = (values: Links): Promise<void> => {
  IndexedDB.putMany(values);
};

export const App: React.FunctionComponent = () => {
  const valuesForTest: Links = [
    {
      href: "https://somelink1.com/",
      name: "Link"
    },
    {
      href: "https://somelink2.com/",
      name: "Link"
    },
    {
      href: "https://somelink3.com/",
      name: "Link"
    },
  ];

  useEffect(() => {
        saveValuesToDB(valuesForTest);
  }, []);

  return (
    <SomeComponent/>
  );
};

你能帮帮我吗?

【问题讨论】:

  • 对于初学者,每次打开数据库时指定相同的 onupgradeneeded 处理程序

标签: javascript reactjs typescript indexeddb


【解决方案1】:

如果您使用第一个代码 sn-ps 创建了数据库,您的“存储”对象存储将使用 id 作为 keyPath。如果您想像在第二个 sn-p 中一样将其更改为 href,请先删除数据库(在浏览器 devtools 中),然后运行您的第二个 sn-p。

请注意,如果您想对现有数据库进行架构更改(而不删除它),您必须将更高的版本号传递给 indexedDB.open 以触发您的onupgradeneeded 回调:indexedDB.open("MyDB", 2);。如果存在相同版本的数据库,则(显然)不会执行该回调,因为它不需要升级。

还请注意,如果您想同时使用代码 sn-ps 来存储不同的内容(值和链接),请为它们使用单​​独的对象存储:createObjectStore("values", { keyPath: "id" })createObjectStore("links", { keyPath: "href" })

最后但同样重要的是,为了更方便地使用 IndexedDB,我真的建议使用 AceBase(成熟的实时数据库)或 Dexie(简单的 IndexedDB 包装器)。这些都易于使用和处理所有 IndexedDB 管道!

编辑:在您的putMany 方法中,我还看到您在open.onsuccess 回调中调用resolve,而不是等到所有put 操作成功。这就是为什么您不会收到错误的原因,reject 将在 resolve 之后被调用,所以什么都不做。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多