如何使用户能够有效地将indexedDB对象存储的内容保存到文件中?

时间:2013-01-21 13:20:00

标签: javascript html5 indexeddb

我在IndexedDB中存储了大量小对象。我想让用户能够将其中一个对象库导出到他们可以“下载”的文件中。

我看过this blog article。其中介绍了如何读取数据,JSON.stringify数据,使用encodeURIComponent对其进行编码,并将其作为href放置,以便用于下载数据的链接。像这样:

var transaction = db.transaction([objectstore], "readonly");
var content = [];
var objectStore = transaction.objectStore(objectstore);

objectStore.openCursor().onsuccess = function(event) {
    var cursor = event.target.result;
    if (cursor) {
        content.push({key:cursor.key,value:cursor.value});
        cursor.continue();
    }
}; 

transaction.oncomplete = function(event) {
    var serializedData = JSON.stringify(dataToStore);
    link.attr("href",'data:Application/octet-stream,'+encodeURIComponent(serializedData));
    link.trigger("click");
};

这很好,除了对象存储将有数百万条记录,我觉得这不会有足够的性能。有没有办法更直接地允许用户将对象存储作为文件保存(我可以通过网页再次导入)。


编辑从评论中的一些注释中我重写了一些如何工作,以便从中获得更多的果汁。新代码类似于:

var transaction = db.transaction([objectstore], "readonly");
var objectStore = transaction.objectStore(objectstore);

objectStore.getAll().onsuccess = function(evt) {
    var url = window.URL.createObjectURL(new Blob(evt.target.results, {'type': 'application/octet-stream'}));
    link.attr('href', url);
    link.trigger('click');
};

这会给我一些结果:

  • 10k记录,平均出口时间975.87ms
  • 100k记录,平均出口时间5,850.10ms
  • 1mil记录,平均出口时间56,681.00ms

正如您所看到的,100万条记录需要大约一分钟才能导出。有没有更好的方法来做这件事? (我也尝试使用游标而不是.getAll(),但游标速度较慢)

1 个答案:

答案 0 :(得分:1)

IDBObjectStore.getAll不是IndexedDB标准的一部分,它使用了一个光标。

  

注意:Mozilla还实现了getAll()来处理这种情况(和   getAllKeys(),目前隐藏在后面   在about:config中的dom.indexedDB.experimental preference。这些不是   IndexedDB标准的一部分,将来可能会消失。我们已经   包括它们因为我们认为它们很有用。以下代码可以   与上面完全相同:

objectStore.getAll().onsuccess = function(event) {
  alert("Got all customers: " + event.target.result);
};
     

查看该值会产生性能成本   游标的属性,因为对象是懒惰创建的。当你   例如,使用getAll(),Gecko必须一次创建所有对象。   如果你只是想看看每个键,感谢   例如,使用游标比使用游标更有效   得到所有()。如果您正在尝试获取所有对象的数组   但是,对象存储使用getAll()。

获取不知道密钥的记录的唯一方法是使用游标。所以不,我不认为有更好的方法。但是你需要问自己这是否比从服务器获取记录更快。