无法使用 indexedDB 保存值
Can't save values using indexedDB
你好,我被 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/>
);
};
而这个总是失败。完全没有错误或异常。只是数据没有保存。
主要区别只是数据类型。第一个示例使用“值”类型,第二个示例使用“链接”类型。
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/>
);
};
你能帮帮我吗?
如果您使用第一个代码片段创建了数据库,您的“存储”对象存储将使用 id
作为 keyPath。如果您想像第二个代码段中那样将其更改为 href
,请先删除数据库(在浏览器开发工具中),然后 运行 您的第二个代码段。
请注意,如果您想对现有数据库进行架构更改(而不是删除它),则必须将更高的版本号传递给 indexedDB.open 以触发您的 onupgradeneeded
回调: indexedDB.open("MyDB", 2);
。如果数据库存在相同版本,则该回调将(显然)不会执行,因为它不需要升级。
另请注意,如果您想使用两个代码片段来存储不同的东西(值和链接),请为它们使用单独的对象存储:createObjectStore("values", { keyPath: "id" })
和 createObjectStore("links", { keyPath: "href" })
最后但同样重要的是,为了更轻松地使用 IndexedDB,我真的可以推荐使用 AceBase (fullblown realtime database) or Dexie(简单的 IndexedDB 包装器)。这些易于使用并处理所有 IndexedDB 管道!
编辑:在您的 putMany
方法中,我还看到您在 open.onsuccess
回调中调用 resolve
,而不是等到所有 put
操作都成功。这就是为什么您不会收到错误的原因,reject
将在 resolve
之后调用,因此什么都不做。
你好,我被 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/>
);
};
而这个总是失败。完全没有错误或异常。只是数据没有保存。 主要区别只是数据类型。第一个示例使用“值”类型,第二个示例使用“链接”类型。
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/>
);
};
你能帮帮我吗?
如果您使用第一个代码片段创建了数据库,您的“存储”对象存储将使用 id
作为 keyPath。如果您想像第二个代码段中那样将其更改为 href
,请先删除数据库(在浏览器开发工具中),然后 运行 您的第二个代码段。
请注意,如果您想对现有数据库进行架构更改(而不是删除它),则必须将更高的版本号传递给 indexedDB.open 以触发您的 onupgradeneeded
回调: indexedDB.open("MyDB", 2);
。如果数据库存在相同版本,则该回调将(显然)不会执行,因为它不需要升级。
另请注意,如果您想使用两个代码片段来存储不同的东西(值和链接),请为它们使用单独的对象存储:createObjectStore("values", { keyPath: "id" })
和 createObjectStore("links", { keyPath: "href" })
最后但同样重要的是,为了更轻松地使用 IndexedDB,我真的可以推荐使用 AceBase (fullblown realtime database) or Dexie(简单的 IndexedDB 包装器)。这些易于使用并处理所有 IndexedDB 管道!
编辑:在您的 putMany
方法中,我还看到您在 open.onsuccess
回调中调用 resolve
,而不是等到所有 put
操作都成功。这就是为什么您不会收到错误的原因,reject
将在 resolve
之后调用,因此什么都不做。