在前面的一篇文章中,咱們已經實現了使用indexedDB實現ajax本地數據存儲的功能,詳情,請看這篇文章。如今咱們須要把上面的一篇文章中的代碼使用promise結構來重構下。咱們爲何須要使用promise來重構呢?咱們以前一直使用 indexedDB中的代碼,可是在indexedDB中,咱們代碼很大程度上依賴於回調,若是咱們的代碼愈來愈多,咱們須要的回調嵌套就愈來愈多,這對於後期代碼維護不是很好。javascript
好比咱們能夠看看咱們以前的代碼以下所示:html
// 打開或建立 store-data 數據庫 var result = window.indexedDB.open('store-data', 3); // 監聽error函數觸發 result.onerror = function(event) { console.log("DataBase error:", event.target.error); } // 監聽當前版本號被升級的時候觸發該函數 result.onupgradeneeded = function(event) { var db = event.target.result; /* 是否包含該對象倉庫名(或叫表名)。若是不包含就建立一個。 該對象中的 keyPath屬性id爲主鍵 */ if (!db.objectStoreNames.contains('store')) { db.createObjectStore("store", { keyPath: "id", autoIncrement: true }); } } result.onsuccess = function(event) { var targetValue = event.target.result; /* 1. 使用 targetValue.transaction(storeName, transactionMode) 來建立事務 2. 建立事務以後,咱們使用 targetValue.transaction(storeName, transactionMode).objectStore(storeName) 這個方法,拿到 IDBObjectStore對象。 */ var objectStore = targetValue.transaction(storeName, transactionMode).objectStore(storeName); var request = objectStore.add({id: 3, name: 'kongzhi12', age: 31}); request.onsuccess = function(event) { console.log('回調函數成功'); } request.onerror = function(event) { console.log("DataBase error:", event.target.error); } }
如上代碼,咱們打開了或建立了一個 store-data 數據庫,而後把onsuccess回調附加到該請求上,在該onsuccess請求上,咱們又有請求事件,接着有 onsuccess 回調函數,依次類推,若是之後代碼愈來愈複雜的時候,咱們之後代碼就一直變成回調嵌套中,所以咱們如今想使用promise方法來重構上面的代碼,咱們想要讓上面的代碼變成以下所示這樣的:java
openDatabase('store-data', 3).then(function(db) { return openObjectStore(db, "store", "readwrite"); }).then(function(objectStore){ return addObject(objectStore, {"id": 3, "name": 'kongzhi123', 'age': 31}); }).then(function(){ console.log('回調成功'); }).catch(function(error) { console.log('DataBase error', error); });
咱們但願變成如上的promise代碼,咱們但願將javascript異步回調的代碼變成咱們的promise代碼。在重構咱們的代碼以前,咱們先來看看咱們的 XMLHttpRequest 代碼,咱們但願使用promise來重構該代碼,在重構以前,咱們先來看看XMLHttpRequest代碼以下:jquery
var xhr = new XMLHttpRequest(); xhr.onload = function() { // 處理響應 }; xhr.onerror = function() { // 處理錯誤 }; xhr.open("get", '/xxx.json', true); xhr.send();
如上這樣的代碼,是咱們以前的xmlHttpRequest代碼,如今咱們可使用咱們的promise來重構咱們上面的代碼,所以重構後的代碼變成以下所示:ios
var promise_XHR = function(url, method) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.onload = resolve; xhr.onerror = reject; xhr.open(method, url, true); xhr.send(); }); };
如上 promise_XHR 函數,該函數接收一個url 和 method參數,並返回了一個promise對象,該promise傳入了一個函數,該函數有兩個參數,表明成功和失敗的回調,而後內部代碼,咱們建立了一個XMLHttpRequest對象,而後該對象 onload 函數的時候 把resolve 成功回調賦值給他,而後 xhr.onerror 函數的時候,把 reject 拒絕函數傳遞給他,咱們調用方式以下所示:git
promise_XHR('/xxx.json', 'get').then(function(){ // 處理成功的回調函數 }).catch(error) { // 處理咱們異常的回調函數 }
如今咱們想把該方式使用到咱們的 store.js 代碼內部來。重構後的代碼就變成了以下:github
import axios from 'axios'; var DB_VERSION = 1; var DB_NAME = 'store-data2'; var openDataBase = function() { return new Promise(function(resolve, reject) { if (!window.indexedDB) { reject("indexedDB not supported"); } // 打開或建立 store-data 數據庫 var result = window.indexedDB.open(DB_NAME, DB_VERSION); // 監聽error函數觸發 result.onerror = function(event) { console.log("DataBase error:", event.target.error); } // 監聽當前版本號被升級的時候觸發該函數 result.onupgradeneeded = function(event) { var db = event.target.result; /* 是否包含該對象倉庫名(或叫表名)。若是不包含就建立一個。 該對象中的 keyPath屬性id爲主鍵 */ if (!db.objectStoreNames.contains('store')) { db.createObjectStore("store", { keyPath: "id", autoIncrement: true }); } } result.onsuccess = function(event) { resolve(event.target.result); } }); }; /* @param {storeName} 倉庫名或表名 @param {transactionMode} 事務模式 readOnly 只讀,readwrite 可讀可寫 */ var openObjectStore = function(db, storeName, transactionMode) { return db.transaction(storeName, transactionMode).objectStore(storeName); }; var getStore = function (successCallback) { return new Promise(function(resolve, reject) { openDataBase().then(function(db) { var objectStore = openObjectStore(db, 'store'); var datas = []; objectStore.openCursor().onsuccess = function(event) { var cursor = event.target.result; if (cursor) { datas.push(cursor.value); cursor.continue(); } else { if (datas.length > 0) { resolve(datas); } else { getDataFromServer().then(function(d) { openDataBase().then(function(db) { var objectStore = openObjectStore(db, "store", "readwrite"); for (let i = 0; i < datas.length; i++) { objectStore.add(datas[i]); } resolve(datas); }); }); } } } }).catch(function() { getDataFromServer().then(function(datas) { resolve(datas); }); }); }); }; function getDataFromServer() { return new Promise(function(resolve, reject) { axios.get("http://localhost:8081/public/json/index.json", resolve); }); } var addToObjectStore = function(storeName, object) { return new Promise(function(resolve, reject) { openDataBase().then(function(db) { openObjectStore(db, storeName, 'readwrite').add(object).onsuccess = resolve; }).catch(function(error) { reject(error); }) }); }; var updateInObjectStore = function(storeName, id, object) { return new Promise(function(resolve, reject) { openDataBase().then(function(db) { openObjectStore(db, storeName, "readwrite").openCursor().onsuccess = function(event) { var cursor = event.target.result; if (!cursor) { reject("store-data not found"); } if (cursor.value.id === id) { cursor.put(object).onsuccess = resolve; return; } cursor.continue(); } }).catch(function(){ reject(error); }) }); } window.openDataBase = openDataBase; window.openObjectStore = openObjectStore; window.addToObjectStore = addToObjectStore; window.updateInObjectStore = updateInObjectStore; window.getStore = getStore;
而後咱們須要在咱們的 myAccount.js 代碼改爲以下初始化所示:ajax
import $ from 'jquery'; $(function() { openDataBase("store-data2", 2).then(function(db) { return openObjectStore(db, "store", "readwrite"); }).then(function(objectStore) { return addToObjectStore("store", {id: 1, name: 'kongzhi111', age: 11}); }).then(function() { console.log('添加成功'); }).catch(function(error) { console.log("數據庫加載失敗", error); }); /* var addStore = function(id, name, age) { var obj = { id: id, name: name, age: age }; addToObjectStore("store", obj); renderHTMLFunc(obj); $.getJSON("http://localhost:8081/public/json/index.json", obj, function(data) { updateDisplay(data); }); }; $("#submit").click(function(e) { addStore(3, 'longen1', '111'); }); $("#update").click(function(e) { $.getJSON("http://localhost:8081/public/json/index.json", {id: 1}, function(data) { updateInObjectStore("store", 1, data); updateDisplay(data); }); }); */ });
而後會向咱們的數據庫中插入一條數據,咱們刷新頁面後查看咱們的本地數據庫以下所示:數據庫
github源碼demo查看json