使用 IndexedDB API ,当用户加载网页时,我在一个事务中创建属于同一数据库的许多objectStore。
我命令这样做,我创建了一个包含许多要创建的对象库的对象,每个对象都有它的名称,数据和索引。
然后一个函数运行该对象并有效地为每个对象创建Database,objectStores和索引。
然而,在所有OS的创建中,只填充了对象的最后一个成员。比如要创建和填充5个对象,创建5个,但只填充最后一个 显然,这是一个覆盖问题或与JS堆栈或异步性有关的问题。
我感谢任何帮助,使代码填充所有操作系统而不是最后一个操作系统 我的浏览器是Chrome 56,我从API中获取数据,其响应正常,而且我在vanillajs上编码。感谢您对vanillajs的帮助,没有办法使用任何与现代Web平台不同的库或框架。
以下是代码:
在HTML方面,这是对象的一个示例:
var datastores = [{osName:'items', osEndpoint: '/api/data/os/1/1', osIndex:'value'}, {osName:'categories', osEndpoint: '/api/data/os/2/1', osIndex: 'idc'}];
关于javascript:
var request = indexedDB.open(DB_NAME, DB_VERSION); // open database.
request.onerror = function (e) { // error callback
console.error("error: " + e.target.errorCode);
};
request.onupgradeneeded = function (e) { // the onupgradeneeded event which creates all schema, dataabase, objectstores and populates OS.
var db = this.result;
for (var i in datastores) { // loop the objectStore object.
var objectStore = db.createObjectStore(datastores[i].osName, {keyPath: "id"});
TB_NAME = datastores[i].osName; // instantiate each objectStore name.
objectStore.createIndex(datastores[i].osIndex, datastores[i].osIndex, { unique: false }); // create each index.
objectStore.transaction.oncomplete = function(e) { // oncomplete event, after creating OS...
fetchGet(datastores[i].osEndpoint, popTable); // runs a function to fetch from a designated endpoint and calls a function.
};
}
}
现在的功能:获取数据和填充数据:
function fetchGet(url, function) { // fetch from API.
fetch(url, {
method: 'GET'
}).then(function(response) {
return response.json();
}).then(function(json) {
popTable (json);
}).catch(function(err) {
console.log('error!', err);
});
}
function popTable(json) {
var m = 0;
var tx = db.transaction(TB_NAME, "readwrite");
tx.oncomplete = function(e) {
console.log("Completed Transaction " + TB_NAME);
};
tx.onerror = function(e) {
console.error("error: " + e.target.errorCode);
};
var txObjectStore = tx.objectStore(TB_NAME);
for (m in json) {
var request = txObjectStore.add(json[m]);
request.onsuccess = function (e) {
console.log('adding... ' );
};
}
}
答案 0 :(得分:0)
for (var i in datastores)
循环同步运行,每次都更新全局TB_NAME
变量。循环结束后,TB_NAME
将保留最后一个对象库的名称。
当异步popTable
调用运行时,TB_NAME
将永远保留最后一个商店的名称,因此这是唯一一个将更新的商店。尝试将日志记录添加到popTable
以查看此内容。
您需要以某种方式传递商店名称的当前值(例如,作为fetchGet的参数)。另请注意,虽然在调用popTable
时将fetchGet
作为参数传递,但实际上并未将其作为参数接受。
...
具体变化:
更改您致电fetchGet
以包含商店名称的方式:
fetchGet(datastores[i].osEndpoint, popTable, datastores[i].osName);
更改fetchGet
功能以接受参数:
function fetchGet(url, func, name) {
然后不要直接调用popTable
,而是执行:
func(json, name);
然后将popTable
的定义更改为:
function popTable(json, name) {
...并在交易中使用name
。