2013-02-16 86 views
4

我遇到了索引数据库的问题。在Firefox 18上,当我创建新数据库时,onsuccess方法被调用的同时有onupgradeneeded。在Chrome 24(这是我想要得到的行为),该onsuccess方法仅称为onupgradeneeded方法完成之后。为什么在连接到indexedDB时onsuccess需要onsuccess有时会被调用?

根据IndexedDB上的MDN信息,我的印象是,当onsuccess方法被调用时,使用数据库是安全的,但这使得它看起来像不在Firefox中。

(function(){ 
    app = {}; 

    // These will hold the data for each store. 
    app.objectstores = [ 
    { name: 'UNIVERSITIES', 
     keyPath: 'UID', 
     autoIncrement: false, 
     data_source: 'http://mysites.dev/nddery.ca_www/larelance/data/universite.json' }, 
    ]; 

    // Some information pertaining to the DB. 
    app.indexedDB = {}; 
    app.indexedDB.db = null 
    app.DB_NAME  = 'testdb'; 
    app.DB_VERSION = 1; 

    /** 
    * Attempt to open the database. 
    * If the version has changed, deleted known object stores and re-create them. 
    * We'll add the data later. 
    * 
    */ 
    app.indexedDB.open = function() { 
    // Everything is done through requests and transactions. 
    var request = window.indexedDB.open(app.DB_NAME, app.DB_VERSION); 

    // We can only create Object stores in a onupgradeneeded transaction. 
    request.onupgradeneeded = function(e) { 
     app.indexedDB.db = e.target.result; 
     var db = app.indexedDB.db; 

     // Delete all object stores not to create confusion and re-create them. 
     app.objectstores.forEach(function(o) { 
     if (db.objectStoreNames.contains(o.name)) 
      db.deleteObjectStore(o.name); 

     var store = db.createObjectStore(
      o.name, 
      { keyPath: o.keyPath, autoIncrement: o.autoIncrement } 
     ); 

     app.indexedDB.addDataFromUrl(o.name, o.data_source); 
     }); 
    }; // end request.onupgradeneeded() 

    // This method is called before the "onupgradeneeded" has finished..?? 
    request.onsuccess = function(e) { 
     app.indexedDB.db = e.target.result; 
     app.ui.updateStatusBar('Database initialized...'); 

     // *** 
     // Would like to query the database here but in Firefox the data has not 
     // always been added at this point... Works in Chrome. 
     // 
    }; // end request.onsuccess() 

    request.onerror = app.indexedDB.onerror; 
    }; // end app.indexedDB.open() 


    app.indexedDB.addDataFromUrl = function(store, url) { 
    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', url, true); 
    xhr.onload = function(event) { 
     if(xhr.status == 200) { 
     console.log('*** XHR successful'); 
     // I would be adding the JSON data to the database object stores here. 
     } 
     else{ 
     console.error("addDataFromUrl error:", xhr.responseText, xhr.status); 
     } 
    }; 
    xhr.send(); 
    }; // end app.indexedDB.addDataFromUrl() 
})(); 

谢谢!

回答

4

一个你可能患同的东西是在IndexedDB的自动提交功能。如果交易在短时间内变为非活动状态,它将提交交易并关闭交易。

在你的情况你调用一个异步方法来填充数据,这就是为什么该交易可能变为无效。如果你在app.indexedDB.addDataFromUrl(o.name,o.data_source)后添加一个console.write,你会发现它会在你的数据被检索之前被调用,导致事务的提交。这就是为什么当成功回调被调用时数据不存在。 Chrome中事务的超时时间可能高于Firefox。规范中没有对它进行描述,因此供应商可能会有所不同。

顺便说一句,如果你想在你的Ajax调用添加数据,你将不得不通过对象存储作为一个参数为好。

+0

的交易Chrome和Firefox中是较高的是有意义的超时。我将尝试使同步AJAX(这是一种反生产)请求,并查看事务是否保持打开状态。预取我的数据,而不是通过AJAX调用将它添加到数据库中解决这个问题?任何其他选项? – nddery 2013-02-17 23:41:49

+0

也许有其他观点。想想这个。保持现在的情况。在onupgradeneeded事件中,您触发ajax调用,并让version_change事务提交。当您收到AJAX调用的回调函数时,您将创建一个到db的新连接,以便插入检索到的数据。当然,这是一个非常简单的表达方式,但如何做到这一点。 – 2013-02-18 09:39:50

0

你有内部if(xhr.status == 200) {} 调用事务做什么从那里,把数据的对象存储和更多你所需要的

编辑:

我不喜欢这样,对我的作品,该功能的onComplete一次所有的数据被插入被调用和对象存储准备就绪:

var xhr = new XMLHttpRequest(); 
xhr.open("GET", "http://...", true); 
xhr.addEventListener("load", function(){ 
    if(xhr.status === 200){ 
     console.info("Data received with success"); 
     var data = JSON.parse(xhr.responseText); 
     var transaction = db.transaction([STORe],'readwrite'); 
     var objstore = transaction.objectStore(STORE); 
     for(i = 0; i < data.length; i++){ 
      objstore.put(data[i]); 
     }; 
     transaction.oncomplete = function(event){ 
      //do what you need here 
      console.info("Inserted data: " + data.length); 
     }; 
     transaction.onerror = function(event){    
     }; 
     transaction.onabort = function(event){ 
     }; 
     transaction.ontimeout = function(event){ 
     }; 
     transaction.onblocked = function(event){ 
     };      
    }; 
}, false); 
xhr.send(); 
+1

是的,这就是我做然而,在''window.indexedDB.open'的onComplete()'方法被调用我添加完在数据库中的所有数据之前 - 这使我的问题。我想知道是否有充分的证据可以在安全使用数据库时发出警报。 – nddery 2013-02-17 23:35:42

+0

这是我做到了,在第一次的方式,但它总是结束了与'oncomplete'方法来叫早和一些'DOM IDBDatabase例外11'错误。我尝试直接在'onupgradeneeded'中移动XMLHttpRequest,但没有取得太大的成功。从那时起,我在尝试打开我的数据库之前预取了我的数据,并直接将它添加到'onupgradeneeded' mehtod中,我没有收到上述任何错误/问题。我认为这种方法唯一的缺点是,即使没有更新需要,我现在总是获取我的数据。 – nddery 2013-02-18 16:28:01

+0

我已经得到了所有的xhr请求和数据处理,在indexedDB.open的onsuccess里面,你试过了吗? – 2013-02-19 09:19:17

相关问题