indexedDB在插入循环后阻止了DOM异常

时间:2014-04-16 10:51:31

标签: javascript indexeddb domexception

我正在使用indexedDB进行一些测试,并且在插入测试期间我一直在阻止chrome。 基本上我正在做的是一个简单的循环,100000次,在db中插入简单的字符串。它正确完成但最后检查器中的indexedDB不可见。甚至没有刷新页面。如果尝试重新加载页面并重新打开数据库,我会得到一个DOM异常。如果关闭镀铬它会挂起,我必须杀死它。

代码下方:

var testIndexedDB = {

  db : null,

  request: null,

  openDB : function(){
    var self = this;
    var request = this.request =  indexedDB.open("web", 1);

    request.onupgradeneeded = function() {
      // The database did not previously exist, so create object stores and indexes.
      request.close();
      var db = request.result;
      var stories = db.createObjectStore("stories", {keyPath: "id"});

    };

    request.onsuccess = function() {
      self.db = request.result;
    };

     request.onerror = function(e) {
      console.log(e);     
    };

    request.onblocked = function(e){
        console.log('blocked')
    }
  },

  addItem: function(store, loid, text){
    var db = this.db;
    var trans = db.transaction(store, "readwrite");
    var store = trans.objectStore(store);
    var request = store.put({
      "id": loid,
      "text" : text
    });

    request.onsuccess = function(e) {
      // Re-render all the todo's

    };

    request.onerror = function(e) {
      console.log(e.value);
    };
  },

  getItem: function(store, loid){
    var db = this.db;
    var trans = db.transaction(store);
    var store = trans.objectStore(store);
    var request = store.get(loid);

    request.onsuccess = function(e) {
      console.log(request.result) // Refresh the screen
    };

    request.onerror = function(e) {
      console.log(e);
    };
  },

  removeItem: function(store, loid){
    var db = this.db;
    var trans = db.transaction(store, "readwrite");
    var store = trans.objectStore(store);
    var request = store.delete(loid);

    request.onsuccess = function(e) {
      console.log('el deleted'); // Refresh the screen
    };

    request.onerror = function(e) {
      console.log(e);
    };
  },

  testSize: function(){
    var i = 0,
        t;

    while(i<100000){
      t = new Date().getTime();
      this.addItem('stories', i, t)
      i++;

    }
    console.log('items added')
  }
};

testIndexedDB.openDB();

只需运行testIndexedDB.testSize()即可发现问题。

如何正确测试连续插入?为什么会发生这种情况?

感谢

1 个答案:

答案 0 :(得分:2)

批处理插入中的主要问题是您打开100000事务并阻止数据库。我已经对您的代码进行了一些优化以进行批量插入,现在插入时间少于5秒。

我不是为每个项目打开单独的事务,而是将项目分组为1000个项目,然后打开该批次的事务。现在交易次数减少到100.以下是所有变更:

首先我创建了一个批量插入功能:

addItems: function(store, items){
    var db = this.db;
    var trans = db.transaction(store, "readwrite"); //uses only one transaction per batch of 1000
    trans.oncomplete = function(e){
        console.log('batch inserted');
    };
    var store = trans.objectStore(store);
    for(var i=0; i<items.length; i++){
        var request = store.put(items[i]);
        request.onerror = function(e) {
            console.log(e.value);
        };
    }
},

然后我改变了插入功能以批量发送数据:

testSize: function(){
    var i = 0,
    t;
    tempList = [];
    while(i<100000){
        t = new Date().getTime();
        tempList.push({
            "id": i,
            "text" : t
        })
        if(i> 0 && i% 1000 == 0){ //items are grouped into a array of 1000 items
            this.addItems('stories', tempList.slice());
            tempList = [];
        }      
        i++;
    }
    console.log('items added');
}