漸進式web應用開發---promise式數據庫(五)

在前面的一篇文章中,咱們已經實現了使用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

相關文章
相關標籤/搜索