IndexedDB 需要时间来初始化另一个函数中需要的外部作用域变量 db
IndexedDB takes time to initialize outer scope variable db which is needed in another function
我正在使用 javascript 使用 indexedDB 打开一个数据库来保存日记条目。我正在对数据库做三件事:显示所有条目、添加条目和删除条目。
尝试创建事务时失败,因为 'db' 是 'undefined.' 我希望在代码尝试创建事务时定义数据库。
错误是在代码行引起的:
const getObjectStore = (storeName, mode) => {
console.log('db: ', db);
const tx = db.transaction(storeName, mode); // error is thrown because db is undefined
return tx.objectStore(storeName);
};
我试着把 console.log 放在不同的地方看看有什么问题。我发现 db 在它被 onsuccess 响应或 onupgradeneeded 响应定义之前需要时间。在使用之前,我看不到任何其他定义 db 的方法。你能告诉我如何在使用 db 之前确保自己对 db 的分配吗?
输出:
> adding something in the diary
> db from getObjectStore: undefined
> Uncaught TypeError: Cannot read property 'transaction' of undefined
at getObjectStore (script.js:35)
at Object.setAnEntry [as add] (script.js:62)
at script.js:81
at script.js:215
getObjectStore @ script.js:35
setAnEntry @ script.js:62
(anonymous) @ script.js:81
(anonymous) @ script.js:215
> there is indexeddb!
> db: IDBDatabase {name: "medDiary", version: 1, objectStoreNames: DOMStringList, onabort: null, onclose: null, …}
我正在使用的所有代码:
// DATABASE FOR THE DIARY
const Dairy = (() => {
if (window.indexedDB) {
let db;
const DB_NAME = 'Dairy';
const DB_VERSION = 1;
const DB_STORE_NAME = 'diaries';
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => {
console.log('Error requesting to open database permission denied.');
};
request.onsuccess = (event) => {
console.log('there is indexeddb!');
db = event.target.result;
console.log('db: ', db);
db.onerror = (evt) => {
console.error(`Database error: ${evt.target.errorCode}`);
};
};
request.onupgradeneeded = (event) => {
db = request.result;
const store = event.currentTarget.result.createObjectStore(DB_STORE_NAME, { keyPath: 'date' });
store.createIndex('subject', 'subject', { unique: false });
store.createIndex('date', 'date', { unique: true });
store.createIndex('description', 'description', { unique: false });
};
const getObjectStore = (storeName, mode) => {
console.log('db from getObjectStore: ', db);
const tx = db.transaction(storeName, mode);
return tx.objectStore(storeName);
};
const getAllEntries = () => new Promise((resolve) => {
const result = [];
const store = getObjectStore(DB_STORE_NAME, 'readonly');
const req = store.openCursor();
req.onsuccess = (evt) => {
const cursor = evt.target.result;
if (cursor) {
const retrive = store.get(cursor.key);
retrive.onsuccess = function (evt) {
const value = evt.target.result;
result.append(value);
};
cursor.continue();
} else {
console.log('No more entries');
resolve(result);
}
};
});
const setAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.put(value);
};
const removeAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.remove(value);
};
return {
all: getAllEntries,
add: setAnEntry,
remove: removeAnEntry,
};
}
alert("Your browser doesn't support a stable version of IndexedDB. Dairy related features will not be available.");
return {};
})();
console.log('adding something in the diary');
console.log('... ', Dairy.add({ subject: 'hello', description: 'bluh bluh', date: Date() }));
console.log('show all: ', Dairy.all());
您可以使用承诺打开数据库:
let promise = new Promise(function(resolve, reject)
{
//check for support
if (!('indexedDB' in window)) {
//console.log('This browser doesn\'t support IndexedDB');
reject("indexedDB not supported");
}
var request = indexedDB.open(dbName, dbVersion);
request.onerror = function (event) {
reject("Error opening DB");
};
request.onsuccess = function (event) {
console.log("opened!");
db = request.result;
resolve(true);
};
});
然后你可以使用:
promise
.then(
result => {
your stuff here sine the DB is now open!!
},
error => console.log(error)
)
传递给 resolve 的参数将作为 'result' 可用。
在您的模块格式中使用:
添加初始化函数:
async function init()
{
let promise = new Promise(function(resolve, reject)
{
//check for support
if (!('indexedDB' in window)) {
//console.log('This browser doesn\'t support IndexedDB');
reject("indexedDB not supported");
}
var request = indexedDB.open(dbName, dbVersion);
request.onerror = function (event) {
reject("Error opening DB");
};
request.onsuccess = function (event) {
console.log("opened!");
db = request.result;
resolve(true);
};
});
let result = await promise;
}
你的模块重写了:
const Dairy = (() => {
if (window.indexedDB)
{
let db;
const DB_NAME = 'Dairy';
const DB_VERSION = 1;
const DB_STORE_NAME = 'diaries';
async function init()
{
let promise = new Promise(function(resolve, reject)
{
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => {
reject('Error requesting to open database permission denied.');
};
request.onsuccess = (event) => {
console.log('there is indexeddb!');
db = event.target.result;
console.log('db: ', db);
db.onerror = (evt) => {
reject("Database error: ${evt.target.errorCode}");
};
resolve(true);
};
request.onupgradeneeded = (event) => {
db = request.result;
const store = event.currentTarget.result.createObjectStore(DB_STORE_NAME, { keyPath: 'date' });
store.createIndex('subject', 'subject', { unique: false });
store.createIndex('date', 'date', { unique: true });
store.createIndex('description', 'description', { unique: false });
};
});
return promise;
}
const getObjectStore = (storeName, mode) => {
console.log('db from getObjectStore: ', db);
const tx = db.transaction(storeName, mode);
return tx.objectStore(storeName);
};
const getAllEntries = () => new Promise((resolve) => {
const result = [];
const store = getObjectStore(DB_STORE_NAME, 'readonly');
const req = store.openCursor();
req.onsuccess = (evt) => {
const cursor = evt.target.result;
if (cursor) {
const retrive = store.get(cursor.key);
retrive.onsuccess = function (evt) {
const value = evt.target.result;
result.append(value);
};
cursor.continue();
} else {
console.log('No more entries');
resolve(result);
}
};
});
const setAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.put(value);
};
const removeAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.remove(value);
};
return {
all: getAllEntries,
add: setAnEntry,
remove: removeAnEntry,
init: init
};
}
alert("Your browser doesn't support a stable version of IndexedDB. Dairy related features will not be available.");
return {};
})();
Dairy.init()
.then(
result => {
console.log('adding something in the diary');
console.log('... ', Dairy.add({ subject: 'hello', description: 'bluh bluh', date: Date() }));
console.log('show all: ', Dairy.all());
},
error => console.log(error)
);
我正在使用 javascript 使用 indexedDB 打开一个数据库来保存日记条目。我正在对数据库做三件事:显示所有条目、添加条目和删除条目。
尝试创建事务时失败,因为 'db' 是 'undefined.' 我希望在代码尝试创建事务时定义数据库。
错误是在代码行引起的:
const getObjectStore = (storeName, mode) => {
console.log('db: ', db);
const tx = db.transaction(storeName, mode); // error is thrown because db is undefined
return tx.objectStore(storeName);
};
我试着把 console.log 放在不同的地方看看有什么问题。我发现 db 在它被 onsuccess 响应或 onupgradeneeded 响应定义之前需要时间。在使用之前,我看不到任何其他定义 db 的方法。你能告诉我如何在使用 db 之前确保自己对 db 的分配吗?
输出:
> adding something in the diary
> db from getObjectStore: undefined
> Uncaught TypeError: Cannot read property 'transaction' of undefined
at getObjectStore (script.js:35)
at Object.setAnEntry [as add] (script.js:62)
at script.js:81
at script.js:215
getObjectStore @ script.js:35
setAnEntry @ script.js:62
(anonymous) @ script.js:81
(anonymous) @ script.js:215
> there is indexeddb!
> db: IDBDatabase {name: "medDiary", version: 1, objectStoreNames: DOMStringList, onabort: null, onclose: null, …}
我正在使用的所有代码:
// DATABASE FOR THE DIARY
const Dairy = (() => {
if (window.indexedDB) {
let db;
const DB_NAME = 'Dairy';
const DB_VERSION = 1;
const DB_STORE_NAME = 'diaries';
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => {
console.log('Error requesting to open database permission denied.');
};
request.onsuccess = (event) => {
console.log('there is indexeddb!');
db = event.target.result;
console.log('db: ', db);
db.onerror = (evt) => {
console.error(`Database error: ${evt.target.errorCode}`);
};
};
request.onupgradeneeded = (event) => {
db = request.result;
const store = event.currentTarget.result.createObjectStore(DB_STORE_NAME, { keyPath: 'date' });
store.createIndex('subject', 'subject', { unique: false });
store.createIndex('date', 'date', { unique: true });
store.createIndex('description', 'description', { unique: false });
};
const getObjectStore = (storeName, mode) => {
console.log('db from getObjectStore: ', db);
const tx = db.transaction(storeName, mode);
return tx.objectStore(storeName);
};
const getAllEntries = () => new Promise((resolve) => {
const result = [];
const store = getObjectStore(DB_STORE_NAME, 'readonly');
const req = store.openCursor();
req.onsuccess = (evt) => {
const cursor = evt.target.result;
if (cursor) {
const retrive = store.get(cursor.key);
retrive.onsuccess = function (evt) {
const value = evt.target.result;
result.append(value);
};
cursor.continue();
} else {
console.log('No more entries');
resolve(result);
}
};
});
const setAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.put(value);
};
const removeAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.remove(value);
};
return {
all: getAllEntries,
add: setAnEntry,
remove: removeAnEntry,
};
}
alert("Your browser doesn't support a stable version of IndexedDB. Dairy related features will not be available.");
return {};
})();
console.log('adding something in the diary');
console.log('... ', Dairy.add({ subject: 'hello', description: 'bluh bluh', date: Date() }));
console.log('show all: ', Dairy.all());
您可以使用承诺打开数据库:
let promise = new Promise(function(resolve, reject)
{
//check for support
if (!('indexedDB' in window)) {
//console.log('This browser doesn\'t support IndexedDB');
reject("indexedDB not supported");
}
var request = indexedDB.open(dbName, dbVersion);
request.onerror = function (event) {
reject("Error opening DB");
};
request.onsuccess = function (event) {
console.log("opened!");
db = request.result;
resolve(true);
};
});
然后你可以使用:
promise
.then(
result => {
your stuff here sine the DB is now open!!
},
error => console.log(error)
)
传递给 resolve 的参数将作为 'result' 可用。
在您的模块格式中使用: 添加初始化函数:
async function init()
{
let promise = new Promise(function(resolve, reject)
{
//check for support
if (!('indexedDB' in window)) {
//console.log('This browser doesn\'t support IndexedDB');
reject("indexedDB not supported");
}
var request = indexedDB.open(dbName, dbVersion);
request.onerror = function (event) {
reject("Error opening DB");
};
request.onsuccess = function (event) {
console.log("opened!");
db = request.result;
resolve(true);
};
});
let result = await promise;
}
你的模块重写了:
const Dairy = (() => {
if (window.indexedDB)
{
let db;
const DB_NAME = 'Dairy';
const DB_VERSION = 1;
const DB_STORE_NAME = 'diaries';
async function init()
{
let promise = new Promise(function(resolve, reject)
{
const request = window.indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => {
reject('Error requesting to open database permission denied.');
};
request.onsuccess = (event) => {
console.log('there is indexeddb!');
db = event.target.result;
console.log('db: ', db);
db.onerror = (evt) => {
reject("Database error: ${evt.target.errorCode}");
};
resolve(true);
};
request.onupgradeneeded = (event) => {
db = request.result;
const store = event.currentTarget.result.createObjectStore(DB_STORE_NAME, { keyPath: 'date' });
store.createIndex('subject', 'subject', { unique: false });
store.createIndex('date', 'date', { unique: true });
store.createIndex('description', 'description', { unique: false });
};
});
return promise;
}
const getObjectStore = (storeName, mode) => {
console.log('db from getObjectStore: ', db);
const tx = db.transaction(storeName, mode);
return tx.objectStore(storeName);
};
const getAllEntries = () => new Promise((resolve) => {
const result = [];
const store = getObjectStore(DB_STORE_NAME, 'readonly');
const req = store.openCursor();
req.onsuccess = (evt) => {
const cursor = evt.target.result;
if (cursor) {
const retrive = store.get(cursor.key);
retrive.onsuccess = function (evt) {
const value = evt.target.result;
result.append(value);
};
cursor.continue();
} else {
console.log('No more entries');
resolve(result);
}
};
});
const setAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.put(value);
};
const removeAnEntry = (value) => {
const store = getObjectStore(DB_STORE_NAME, 'readwrite');
store.remove(value);
};
return {
all: getAllEntries,
add: setAnEntry,
remove: removeAnEntry,
init: init
};
}
alert("Your browser doesn't support a stable version of IndexedDB. Dairy related features will not be available.");
return {};
})();
Dairy.init()
.then(
result => {
console.log('adding something in the diary');
console.log('... ', Dairy.add({ subject: 'hello', description: 'bluh bluh', date: Date() }));
console.log('show all: ', Dairy.all());
},
error => console.log(error)
);