IndexedDB - Microsoft Edge .getAll方法

时间:2018-02-14 23:11:10

标签: javascript microsoft-edge indexeddb

就在最近,我一直在使用IndexedDB - 主要使用Google Chrome作为我的调试工具。不幸的是,我很快就偶然发现一个严重与浏览器之间不兼容相关的问题 - Edge似乎不支持IDBObjectStore接口上的.getAll method, 哎呀.get方法似乎也很棘手 - 到目前为止我所有的尝试都导致了以下错误信息:

  

无法获取未定义或空引用的属性“消息”

使用以下代码:

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)实现.getAll方法最合适的方法是什么,而不必依赖第三方库,如Dexie.js?我假设即使迭代所有可用的对象都有效,但在性能方面它仍然不是最明智的想法。

b)如何让get方法在Edge中工作 - 已经单独解决了它,不知怎的,以下片段解决了,获得所有值仍然是,至于现在,对我来说是一个谜:|

db.transaction('object').objectStore('object').get(1).onsuccess = function(event) {
    console.log(event.target.result);
};

2 个答案:

答案 0 :(得分:0)

好吧,我当然是个dummie,找到了解决方案here,我完全不知道在早些时候寻找解决方案时我是如何设法错过的。请改用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);
    }
};

答案 1 :(得分:0)

错误消息表明handler变量为null。在升级处理程序完成之后,您确定要等待启动新事务吗?一种可靠的方法是确保数据库打开请求已经解决。从它的外观来看,你的代码并没有这样做。要等待,请执行以下操作:

var openRequest = indexedDB.open...;
openRequest.onsuccess = function() {
  var db = openRequest.result;
  var handle = db.transaction...;
  // ...
};

实际上,我不知道你为什么要以这种方式调用handler.get。没有IDBTransaction.prototype.get方法。

此外,您可能希望查看承诺,以帮助您更清楚地构建流程。这是一个例子:

 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);
   }
 }