0

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

代码下方:

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()即可注意到问题。

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

谢谢

4

1 回答 1

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');
}
于 2014-04-16T14:08:44.313 回答