2013-02-16 29 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

相關問題