代码之家  ›  专栏  ›  技术社区  ›  Maciej21592

IndexedDB-Microsoft Edge。getAll方法

  •  -1
  • Maciej21592  · 技术社区  · 6 年前

    就在最近,我一直在玩IndexedDB——主要使用谷歌Chrome作为我的调试工具。不幸的是,我很快就发现了一个与浏览器之间的不兼容性密切相关的问题—Edge似乎不支持 .getAll method 在IDBObjectStore接口上, 见鬼去吧。get方法似乎也很棘手-到目前为止,我所有的尝试都会导致以下错误消息:

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

    使用以下代码:

    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 回复  |  直到 6 年前
        1
  •  0
  •   Josh    6 年前

    错误消息表明处理程序变量为null。是否确实要等到升级处理程序完成后才能启动新事务?一种确保的方法是确保数据库打开请求已解决。从外观上看,您的代码没有做到这一点。要等待,请执行以下操作:

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

    事实上,我不知道你为什么打电话给handler。那样做吧。没有IDBTransation。原型获取方法。

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

     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);
       }
     }
    
        2
  •  0
  •   Maciej21592    6 年前

    好吧,我正式是个傻瓜,找到了解决办法 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);
        }
    };