在同一数据库中创建并行存储时出现IndexedDB同步问题

3pmvbmvn  于 2022-12-09  发布在  IndexedDB
关注(0)|答案(1)|浏览(185)

每当我试图在同一个数据库中同时创建不同的存储时,只有其中一个被创建。有没有办法解决这个同步问题?

bprjcwpo

bprjcwpo1#

我已经能够解决这个问题了,但是我将阐明我的观点,以防它可能会帮助其他人。我有一个GridView组件,它被Map了多次。这个组件保存列,它们是如何排列的,以及它们的特定行为是如何存储在indexedDB中的。(同一数据库中的每个GridView一个)。为了同时创建所有存储(在这种情况下,我必须创建9个)我必须为每个新商店触发版本更改,以便能够持久保存信息。在函数内部,我搜索了Db的实际版本,并添加了1来触发版本更改事件。问题在于,因为在此函数中同步搜索版本,所以所有迭代都获得相同的版本,结果将是因为只有Map的第一次迭代才会触发版本更改,所以只创建了第一个存储。为了解决这个问题,我在Map函数中使用了索引属性,并将其作为顺序属性传递给GridView组件。然后,不再触发版本更改(version+1)在函数中,我用version+order触发了,这样所有的商店都被创建了,因为它确保了所有的版本都比以前的版本高。
我将给予一些代码来帮助解释。
这是Map:

{status.map((status, index) => {
   return (
     <GridView
        pageName={"Page"} // DB Name
        gridName={status} // Store Name
        order={index + 1} // index + 1 so that the order is never 0
        //all the other props...
     />
   );
})}

在GridView组件中,我有一个函数,它在第一次呈现时触发,以搜索数据库中的存储,如果数据库中没有信息,则创建存储,然后用所需的信息填充存储。
我的天

  • @参数{字符串}数据库名称
  • @参数{字符串}存储名称
  • @参数{字符串}密钥路径
  • @参数{整数}顺序
  • @param {对象/数组}信息
  • @返回{对象}:解决:{成功,消息,存储信息},拒绝:{错误,消息}
*/
    const createAndPopulateStore = (
    DB_NAME,
    STORE_NAME,
    keyPath,
    order = 1,
    info
  ) => {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(DB_NAME);

      request.onsuccess = function (e) {
        let database = e.target.result;
        let version = parseInt(database.version);
        database.close();
        //This was the critical part in order to create multiple stores at the same time.
        let secondRequest = indexedDB.open(DB_NAME, version + order); 
        secondRequest.onupgradeneeded = (e) => {
          let database = e.target.result;
          //Early return if the store already exist.
          if (database.objectStoreNames.contains(STORE_NAME)) {
            reject({
              success: false,
              message: `There is already a store named: ${STORE_NAME} created in the database: ${DB_NAME}`,
            });
            return;
          }

          let objectStore = database.createObjectStore(STORE_NAME, { keyPath });
          if (info) {
            // Populates the store within the db named after the gridName prop with the indexedColumns array.
            if (Array.isArray(info)) {
              info.map((item) => objectStore.put(item));
            } else {
              Object.entries(info).map((item) => objectStore.put(item));
            }
          }
        };
        secondRequest.onsuccess = function (e) {
          resolve({
            success: true,
            message: `Store: ${STORE_NAME}, created successfully.`,
            storeInfo: info ?? {},
          });
          let database = e.target.result;
          database.close();
        };
      };
    });
  };

我希望这会有所帮助!自由地问任何关于这个问题的问题,我会尽快回答他们。

相关问题