在同一数据库中创建并行存储时出现 IndexedDB 同步问题
IndexedDB syncronism issue when creating parallel stores in the same db
每当我尝试在同一个数据库中同时创建不同的商店时,只会创建其中一个。有没有办法解决这个融合问题。
我已经能够解决这个问题,但我会澄清我的想法,以防它可能对其他人有所帮助。我有一个多次映射的 GridView 组件。该组件保存列、它们的排列方式以及它们的特定行为以存储在 indexedDB 中。我遇到的问题是我使用了一个函数来创建一个以页面和商店命名的 Db(一个用于同一 DB 中的每个 GridView)。为了同时创建所有商店(在这种情况下,我必须创建其中的 9 个),我必须为每个新商店触发版本更改,以便能够保留信息。在函数内部,我搜索了 Db 实际版本并添加了 1 以触发版本更改事件。问题在于,因为他们在此函数内同步搜索版本,所有迭代都获得相同的版本,结果将是只有第一个商店被创建,因为只有地图的第一次迭代会触发版本更改。为了解决这个问题,我在 map 函数旁边使用了 index prop,并将它作为 order prop 传递给我的 GridView 组件。然后,不是在我使用版本+顺序触发的函数内部触发版本更改(版本+1),而是通过这种方式创建所有商店,因为它确保所有版本都将高于以前的版本。
我会给出一些代码来帮助解释。
这是地图:
{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 {String} DB_NAME
- @param {String} STORE_NAME
- @param {String} keyPath
- @param {Int} 订单
- @param {Object/Array} 信息
- @returns {对象}:解析:{成功,消息,storeInfo),拒绝:{错误,消息}
*/
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();
};
};
});
};
希望对您有所帮助!欢迎提出有关此问题的任何问题,我会尽快回答。
每当我尝试在同一个数据库中同时创建不同的商店时,只会创建其中一个。有没有办法解决这个融合问题。
我已经能够解决这个问题,但我会澄清我的想法,以防它可能对其他人有所帮助。我有一个多次映射的 GridView 组件。该组件保存列、它们的排列方式以及它们的特定行为以存储在 indexedDB 中。我遇到的问题是我使用了一个函数来创建一个以页面和商店命名的 Db(一个用于同一 DB 中的每个 GridView)。为了同时创建所有商店(在这种情况下,我必须创建其中的 9 个),我必须为每个新商店触发版本更改,以便能够保留信息。在函数内部,我搜索了 Db 实际版本并添加了 1 以触发版本更改事件。问题在于,因为他们在此函数内同步搜索版本,所有迭代都获得相同的版本,结果将是只有第一个商店被创建,因为只有地图的第一次迭代会触发版本更改。为了解决这个问题,我在 map 函数旁边使用了 index prop,并将它作为 order prop 传递给我的 GridView 组件。然后,不是在我使用版本+顺序触发的函数内部触发版本更改(版本+1),而是通过这种方式创建所有商店,因为它确保所有版本都将高于以前的版本。
我会给出一些代码来帮助解释。
这是地图:
{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 {String} DB_NAME
- @param {String} STORE_NAME
- @param {String} keyPath
- @param {Int} 订单
- @param {Object/Array} 信息
- @returns {对象}:解析:{成功,消息,storeInfo),拒绝:{错误,消息}
*/
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();
};
};
});
};
希望对您有所帮助!欢迎提出有关此问题的任何问题,我会尽快回答。