天天看點

HTML5-indexedDB使用常見錯誤總結

indexedDB使用過程中常常會出現以下錯誤:

Failed to execute ‘createObjectStore’ on ‘IDBDatabase’: The database is not running a version change transaction.      

這是由于你在success事件的回調中調用createObjectStore方法,該方法應該在upgradeneeded事件的回調中調用。

\\擷取indexedDB對象
const indexedDB = window.indexedDB || window.webkitIndexedDB || 
window.mozIndexedDB;
\\打開資料庫,在回調中建立store object
const request = indexedDB.open(DBName, version);
request.onsuccess = (e) => {
this.db = e.target.result;
};
request.onupgradeneeded = (e) => {
this.db = e.target.result;
if(!this.db.objectStoreNames.contains(storeName)){
this.store = this.db.createObjectStore(storeName, { keyPath: 'key'});
}
}
request.onerror = (e) => {console.log('Can not open indexedDB', e);};      

這裡還可能出現另一個錯誤:

Failed to exectue ‘transaction’ on ‘IDBDatabase’: One of the specified stores was not found.      

這是因為upgradeneeded事件沒有被觸發。

這裡需要注意upgradeneeded事件。首先,根據API,應該在upgradneeded事件的回調函數中調用createObjectStore方法建立store object,不應該在success的回調中,否則會報錯。其次,當為open方法傳入一個本域沒有的資料庫名時,會建立相應的資料庫,并觸發success、upgradeneeded事件,進而建立一個store object。但是,chrome54并不會觸發upgradeneeded事件,造成store object不會被建立,後續在store object上建立事務并操作資料時候就會報錯。Stackoverflow上提供的解決辦法是,在open方法傳入第二個參數(與已有version不同,且更大),這樣就會觸發chrome上的upgradeneeded事件了。不過,每次都需要調用db.version擷取目前的版本号。

另外可能出現的一個錯誤是:

Cannot read property ‘createObjectStore’ of undefined      

這是因為indexedDB是異步的,你必須在回調函數中使用createObjectStore方法,即使你把createObjectStore調用寫在open函數後面,也無法保證哪個先完成。