IndexedDB是一種在瀏覽器端存儲數據的方式,它豐富了客戶端的查詢方式,由於是本地存儲,可以有效減少網路對頁面數據的影響。這使得瀏覽器可以存儲更多的數據,從而豐富了瀏覽器端的應用類型。 IndexedDB與傳統的關係型資料庫不同,它是一個key-value型的資料庫。其中,value可以是複雜的 ...
IndexedDB是一種在瀏覽器端存儲數據的方式,它豐富了客戶端的查詢方式,由於是本地存儲,可以有效減少網路對頁面數據的影響。這使得瀏覽器可以存儲更多的數據,從而豐富了瀏覽器端的應用類型。
IndexedDB與傳統的關係型資料庫不同,它是一個key-value型的資料庫。其中,value可以是複雜的結構體對象,而key可以是對象的某些屬性值,也可以是其他的對象(包括二進位對象)。使用對象中的任何屬性作為index,可以加快查找速度。此外,IndexedDB是自帶transaction的,所有的資料庫操作都會綁定到特定的事務上,並且這些事務是自動提交的,IndexedDB並不支持手動提交事務。
IndexedDB是一種NoSQL資料庫,面向對象,主要存儲的是Javascript對象。而且,IndexedDB的API大部分都是非同步的,使用非同步方法時,API不會立即返回要查詢的數據,而是返回一個callback。
總的來說,IndexedDB為瀏覽器提供了更強大的數據存儲和查詢能力,使開發者能夠創建更豐富、更複雜的瀏覽器端應用。
以下是IndexedDB的一個使用案例:
module.exports = { dbName: 'dbTest', version: 1, db: null, indexedDB: window.indexedDB || window.webkitIndexedDB, // 非同步方法改寫,包括錯誤處理的優化 async openDB() { try { const request = this.indexedDB.open(this.dbName, this.version); // 如果資料庫不存在或者版本號更高,觸發 onupgradeneeded 事件 request.onupgradeneeded = (event) => { this.db = event.target.result; // 確保資料庫中已經包含了所有必要的對象存儲 ['mystore', 'mystore01'].forEach(storeName => { if (!this.db.objectStoreNames.contains(storeName)) { // 如果沒有名為 'mystore' 的對象存儲 this.db.createObjectStore(storeName, { keyPath: 'id' }); // 創建新的對象存儲,並設置主鍵為 'id' } }); }; request.onsuccess = (event) => { this.db = event.target.result; console.log("Database opened successfully", event.target.result); }; request.onerror = (event) => { console.error("Error opening IndexedDB:", event.target.errorCode); }; } catch (error) { console.error("Error opening IndexedDB asynchronously:", error); } }, // 使用Promise替代回調,優化非同步處理 async addData(myStore, data) { try { const store = this.getStore(myStore); return new Promise((resolve, reject) => { const addRequest = store.add(data); addRequest.onsuccess = (event) => { console.log('添加成功!', event.target.result); resolve(event.target.result); }; addRequest.onerror = (event) => { console.log('添加失敗!', event.target.error); reject(event.target.error); }; }); } catch (error) { console.error("Error adding data:", error.name, error.message); throw error; // 重新拋出錯誤,以便調用者可以捕獲 } }, getById(myStore, id) { return new Promise((resolve, reject) => { const store = this.getStore(myStore); const request = store.get(id); request.onerror = (event) => { console.error('查詢數據失敗:', event.target.error); reject(event.target.error); }; request.onsuccess = (event) => { const result = event.target.result; console.log('查詢數據成功:', result); resolve(result); }; }); }, // 更新數據方法 updateById(myStore, data) { return this._handleDatabaseRequest(() => { const store = this.getStore(myStore); return store.put(data); }, '更新數據'); }, // 刪除數據方法 deleteById(myStore, id) { return this._handleDatabaseRequest(() => { const store = this.getStore(myStore); return store.delete(id); }, '刪除數據'); }, getStore(myStore) { if (!this.db) { this.openDB(); // 確保資料庫已經打開 } if (!this.db.objectStoreNames.contains(myStore)) { throw new Error(`Object store ${myStore} does not exist.`); } const transaction = this.db.transaction(myStore, 'readwrite'); const store = transaction.objectStore(myStore); return store; }, // 私有方法,用於處理資料庫請求,減少代碼重覆 _handleDatabaseRequest (operation, actionName) { try { return new Promise((resolve, reject) => { const request = operation(); request.onsuccess = (event) => { console.log(`${actionName}成功:`, event.target.result); resolve(event.target.result); }; request.onerror = (event) => { console.error(`${actionName}失敗:`, event.target.error); reject(event.target.error); }; }); } catch (error) { console.error(`Error during ${actionName}:`, error.name, error.message); throw error; } } }