因此,对于我的周末项目,我选择了学习IndexedDB。我试图创建像DAO这样的东西(对不起,它是我的Java开发人员)。这就是我所拥有的:
7
我用HTML按钮触发:
function ReceiptDB() {
this.db = null;
this.dbname = "Receipts";
this.dbver = 2;
this.getDB = function() {
return db;
};
this.setDB = function(dbresult) {
db = dbresult;
};
var topThis = this;
this.initialize = function() {
alert("Running init");
var promise = $.Deferred();
var request = indexedDB.open(this.dbname, this.dbver);
request.onsuccess = function(e) {
topThis.db = e.target.result;
topThis.setDB(e.target.result);
promise.resolve();
};
request.onupgradeneeded = function(e) {
console.log("Upgrading database");
var db = event.target.result;
if (!db.objectStoreNames.contains("GroupIDs")) {
var groupIdObjectStore = db.createObjectStore("GroupIDs");
}
if (!db.objectStoreNames.contains("Locations")) {
var storesObjectStore = db.createObjectStore("Locations");
}
};
request.onfailure = function(e) {
alert("failed to open db");
//topThis.initPromise.reject();
promise.reject();
};
request.onerror = function(e) {
alert("init error: " + e.target.errorCode);
promise.reject();
};
return promise;
};
this.getAllGroupIds = function() {
var promise = $.Deferred();
var results = [];
var db = topThis.db;
if (!db) {
alert("DB not initialized!");
}
var tx = topThis.db.transaction("GroupIDs", "readonly");
var store = tx.objectStore("GroupIDs");
store.openCursor().onsuccess = function(e) {
var cursor = event.target.result;
if (cursor) {
results.push(cursor.value);
cursor.continue();
}
promise.resolve(results);
};
return promise;
};
this.init();
};
我使用promise来确保对象在尝试对其运行查询之前初始化数据库。不幸的是,它不起作用:当我调用getAllGroupIds()方法时,db为null。对我来说,这应该通过init方法来处理。
谁能告诉我哪里出错了?
编辑:我将init函数重命名为initialize()并手动调用它,因为构造函数调用值没有多大意义。 杰森
编辑2 :在我看到Josh回答之前,我改变了方向。不过,我仍然使用承诺。
$(document).ready(function() {
$("#btn1").click(function(e) {
var receiptdb = new ReceiptDB();
var initPromise = receiptdb.initialize();
$.when(initPromise).done(function() {
console.log("receiptdb promise done");
var getAllPromise = receiptdb.getAllGroupIds();
});
});
}
此时,只要承诺得到解决,我就可以创建一个存储库:
function openDatabase(DBNAME, DBVER) {
var promise = $.Deferred();
var request = window.indexedDB.open(DBNAME, DBVER);
request.onsuccess = function(e) {
console.log("Successfully opened DB");
promise.resolve(e.target.result);
};
request.onupgradeneeded = function(e) {
console.log("configuring database");
// create datastores and indexes
};
request.onfailure = function(e) {
promise.reject();
};
request.onerror = function(e) {
console.log("Error opening database: " + e.target.errorCode);
promise.reject();
};
}
我不喜欢嵌套的$。但很多,但它似乎对我有用
答案 0 :(得分:1)
首先猜测,当你将e.target.result分配给topThis.db时。您只需将保证在其范围或相关范围内有效的值分配给独立的外部范围。
我建议花一些时间学习在继续之前编写异步js。此外,我个人建议避免承诺,因为考虑到问题的本质,您正在经历的所有事情都在增加问题的复杂性,甚至使其模糊不清。
简而言之,不是引用全局db变量来响应onclick,而是打开一个新连接。接下来,将其作为第一个参数传递给其他函数。此外,与编写异步代码有关,而不是尝试编写返回值的函数,而是编写将结果传递给回调函数的函数。
为了帮助您入门,请确保您了解以下内容:
var x;
function setOuterX() {
x = 'Hello World';
}
setTimeout(setOuterX, 0);
console.log(x);