Javascript IndexedDB需要时间来初始化另一个函数所需的外部作用域变量db
我正在使用indexedDB打开一个数据库,使用javascript保存日记条目。我对数据库做了三件事:显示所有条目、添加条目和删除条目 它尝试创建事务时失败,因为“db”是“未定义的”。我希望在代码尝试创建事务时定义db 代码为的行出现错误:Javascript IndexedDB需要时间来初始化另一个函数所需的外部作用域变量db,javascript,indexeddb,Javascript,Indexeddb,我正在使用indexedDB打开一个数据库,使用javascript保存日记条目。我对数据库做了三件事:显示所有条目、添加条目和删除条目 它尝试创建事务时失败,因为“db”是“未定义的”。我希望在代码尝试创建事务时定义db 代码为的行出现错误: const getObjectStore = (storeName, mode) => { console.log('db: ', db); const tx = db.transaction(store
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响应或OnUpgradeRequired响应定义之前需要一段时间。在使用db之前,我看不到任何其他定义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)
);
我试图使用模块模式,我必须返回一个设置为日记的对象。如何从then()返回一个值以设置为Diary?为您的模块创建一个init函数。与异步函数init()类似。里面你可以用:让结果=等待承诺;这将等待承诺的结束。我将更新answer我不明白异步函数init()是如何使用的,或者是如何与您以前的答案结合在一起的。我将把从数据库中添加和删除的函数放在哪里?我理解使用承诺,然后按照承诺行事。你在async上找不到我了。请检查我的答案,然后再试。请看你在那里做了什么。它可以工作,但我必须调用init,然后每次使用数据库时都使用数据库。不过,也许我是第一次这样做,然后在外部进行正常的调用,继续进行数据库交互。如果我将代码复制到外部文件,并在没有模块模式的情况下导入它,那么它可以正常工作,看起来很不错。但我从你的回答中学到了很多。非常感谢。可能重复的