IndexedDB - Microsoft Edge .getAll 方法
IndexedDB - Microsoft Edge .getAll method
最近我一直在玩弄 IndexedDB - 主要使用 Google Chrome 作为我的调试工具。不幸的是,我很快就偶然发现了一个与浏览器之间的不兼容严格相关的问题——Edge 似乎不支持 IDBObjectStore 接口上的 .getAll method,
哎呀 .get 方法似乎也很棘手 - 到目前为止我的所有尝试都导致了以下错误消息:
Unable to get property 'message' of undefined or null reference
使用以下代码:
var db;
function estabilishConnection(callback) {
var req = indexedDB.open('database', 1);
req.onsuccess = function (evt) {
db = evt.target.result;
callback();
}
req.onupgradeneeded = function (evt) {
var target = evt.currentTarget;
var store = target.result.createObjectStore('object', {autoIncrement: true});
store.add("sample1");
store.add("sample2");
store.add("sample3");
}
}
function retrieveItems() {
var transaction = db.transaction("object", "readonly");
var handler = transaction.objectStore("object");
var countRequest = handler.count();
var total;
countRequest.onsuccess = function() {
total = countRequest.result;
for (var i = 0; i < total; i++) {
var get = handler.get(i);
console.log(get);
}
}
}
estabilishConnection(function(evt) {
retrieveItems()
});
我的问题是:
a) 无需依赖 Dexie.js 等第三方库即可实现 .getAll 方法的最合适方法是什么?我假设即使遍历所有可用对象都有效,它仍然不是性能方面最明智的想法。
b) 如何让 get 方法在 Edge 中工作
-- 已经单独解决了它,不知何故下面的代码片段成功了,尽管获取所有值仍然是,至于现在,对我来说还是个谜:|
db.transaction('object').objectStore('object').get(1).onsuccess = function(event) {
console.log(event.target.result);
};
好吧,我正式是个傻瓜,找到了解决方案here, I have absolutely no clue how I managed to miss it when searching for the solution earlier. Use IDBCursor接口。这是代码中的解决方案,以防有人遇到类似问题。
var retrievedItems = [];
db.transaction('object').objectStore('object').openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
retrievedItems.push(cursor.value);
cursor.continue();
} else {
// no more keys remaining
console.log(retrievedItems);
}
};
错误消息表明处理程序变量为空。您确定要等到升级处理程序完成后才开始新事务吗?一种确定的方法是确保数据库打开请求已经解决。从它的外观来看,您的代码不会那样做。要等待,请执行以下操作:
var openRequest = indexedDB.open...;
openRequest.onsuccess = function() {
var db = openRequest.result;
var handle = db.transaction...;
// ...
};
实际上,我不明白你为什么要这样称呼 handler.get。没有IDBTransaction.prototype.get方法。
此外,您可能想要研究 promises 以帮助您更清晰地构建流程。这是一个例子:
function open(name, version, upgradeHandler) {
return new Promise(function(resolve, reject) {
var request = indexedDB.open(name,version);
request.onupgradeneeded = upgradeHandler;
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
function myUgpradeHandler(event) {
var db = event.target.result;
var store = db.createObjectStore(...);
}
function getItems(db) {
return new Promise(function(resolve, reject) {
var tx = db.transaction(...);
var request = tx.getAll();
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
async function foo() {
var db = await open(name, version, myUpgradeHandler);
var items = await getItems(db);
for(var item of items) {
console.log(item);
}
}
最近我一直在玩弄 IndexedDB - 主要使用 Google Chrome 作为我的调试工具。不幸的是,我很快就偶然发现了一个与浏览器之间的不兼容严格相关的问题——Edge 似乎不支持 IDBObjectStore 接口上的 .getAll method, 哎呀 .get 方法似乎也很棘手 - 到目前为止我的所有尝试都导致了以下错误消息:
Unable to get property 'message' of undefined or null reference
使用以下代码:
var db;
function estabilishConnection(callback) {
var req = indexedDB.open('database', 1);
req.onsuccess = function (evt) {
db = evt.target.result;
callback();
}
req.onupgradeneeded = function (evt) {
var target = evt.currentTarget;
var store = target.result.createObjectStore('object', {autoIncrement: true});
store.add("sample1");
store.add("sample2");
store.add("sample3");
}
}
function retrieveItems() {
var transaction = db.transaction("object", "readonly");
var handler = transaction.objectStore("object");
var countRequest = handler.count();
var total;
countRequest.onsuccess = function() {
total = countRequest.result;
for (var i = 0; i < total; i++) {
var get = handler.get(i);
console.log(get);
}
}
}
estabilishConnection(function(evt) {
retrieveItems()
});
我的问题是:
a) 无需依赖 Dexie.js 等第三方库即可实现 .getAll 方法的最合适方法是什么?我假设即使遍历所有可用对象都有效,它仍然不是性能方面最明智的想法。
b) 如何让 get 方法在 Edge 中工作 -- 已经单独解决了它,不知何故下面的代码片段成功了,尽管获取所有值仍然是,至于现在,对我来说还是个谜:|
db.transaction('object').objectStore('object').get(1).onsuccess = function(event) {
console.log(event.target.result);
};
好吧,我正式是个傻瓜,找到了解决方案here, I have absolutely no clue how I managed to miss it when searching for the solution earlier. Use IDBCursor接口。这是代码中的解决方案,以防有人遇到类似问题。
var retrievedItems = [];
db.transaction('object').objectStore('object').openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
retrievedItems.push(cursor.value);
cursor.continue();
} else {
// no more keys remaining
console.log(retrievedItems);
}
};
错误消息表明处理程序变量为空。您确定要等到升级处理程序完成后才开始新事务吗?一种确定的方法是确保数据库打开请求已经解决。从它的外观来看,您的代码不会那样做。要等待,请执行以下操作:
var openRequest = indexedDB.open...;
openRequest.onsuccess = function() {
var db = openRequest.result;
var handle = db.transaction...;
// ...
};
实际上,我不明白你为什么要这样称呼 handler.get。没有IDBTransaction.prototype.get方法。
此外,您可能想要研究 promises 以帮助您更清晰地构建流程。这是一个例子:
function open(name, version, upgradeHandler) {
return new Promise(function(resolve, reject) {
var request = indexedDB.open(name,version);
request.onupgradeneeded = upgradeHandler;
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
function myUgpradeHandler(event) {
var db = event.target.result;
var store = db.createObjectStore(...);
}
function getItems(db) {
return new Promise(function(resolve, reject) {
var tx = db.transaction(...);
var request = tx.getAll();
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
async function foo() {
var db = await open(name, version, myUpgradeHandler);
var items = await getItems(db);
for(var item of items) {
console.log(item);
}
}