1. 背景
在一些專案中,有時候會出現不同模塊重復請求大量相同api介面的情況,特別是在一些功能相似的后臺管理頁面中,以下面這幾個頁面為例,每次進入頁面都需要請求等大量重復的下拉框資料,下拉框資料短時間內改動不大,但也不能在前端使用靜態資料,所以可以考慮在前端進行資料快取,避免重復請求api,



2. 實作思路
主要有以下3個步驟:
- 初次獲取資料,從服務器中請求資料;
- 建立一個映射表,將下拉框資料保存起來,并同時記錄該資料的時間戳;
- 后續再次請求時,首先從映射表中查找資料,如果可以查到資料且資料沒過期,則直接使用資料,否則重新從服務器中獲取資料;
3. 具體實作
3.1 初次獲取資料
以下代碼中,首先呼叫 getLocalData 方法查找快取,如果沒找到快取,就向服務器請求資料(this.$api.task.getCateListAll),獲取到資料后用 setLocalData 方法把資料快取起來,
// 任務型別下拉框資料
// 首先判斷是否有快取
if (!this.getLocalData('cate')) {
/** 初次請求資料 */
await this.$api.task.getCateListAll().then((res) => {
this.m_taskPropOption.cate = this.$u.array.arrToSelect(res.data); // 使用資料
this.m_taskPropDict.cate = this.$u.array.arrToObj(this.m_taskPropOption.cate, "id"); // 使用資料
this.setLocalData('cate'); // 快取資料
});
}
3.2 建立映射表,快取資料
快取資料主要使用了瀏覽器的API localStorage,如下面代碼中 setLocalData 方法,每次從服務器獲取資料后,根據 key 將資料保存在 localStorage 中,并且同時記錄時間戳,記錄時間戳是為了后面檢查快取資料的過期時間:
/** 設定快取 - 建立映射表 */
setLocalData(key) {
// 快取資料
localStorage.setItem(`task_${key}_option`, JSON.stringify(this.m_taskPropOption[key])); // 快取資料
localStorage.setItem(`task_${key}_dict`, JSON.stringify(this.m_taskPropDict[key])); // 快取資料
localStorage.setItem(`task_${key}_timestamp`, Date.now()); // 記錄時間戳
}
3.3 查找快取資料
根據方法 getLocalData ,首先根據 key 從 localStorage 中查找快取的時間戳(時間戳是在快取資料時一起保存的,如果有時間戳,則表示有快取資料),如果有快取時間并且判斷快取時間未過期,則進一步從快取中獲取資料給到程式使用:
/** 獲取快取 - 查找映射表 并 檢查過期時間 */
getLocalData(key) {
let storageTimestamp = localStorage.getItem(`task_${key}_timestamp`);
let expires = 1000 * 3600; // 有效時間
let timestamp = Date.now(); // 當前時間戳
// 從快取中取資料(1h內資料)
if (storageTimestamp && (timestamp - storageTimestamp) < expires) {
let option = localStorage.getItem(`task_${key}_option`); // 從快取中拿到資料給程式使用
let dict = localStorage.getItem(`task_${key}_dict`); // 從快取中拿到資料給程式使用
this.m_taskPropOption[key] = JSON.parse(option);
this.m_taskPropDict[key] = JSON.parse(dict);
return true;
}
return false;
}
3.4 實作效果
使用快取前進入頁面:

使用快取后進入頁面:

由上圖可以看出,使用快取前進入頁面需要請求7個api介面,而快取了資料之后,進入頁面只需要請求3個介面即可,確實起到了減少了請求介面數量的效果,
4. 方案的不足之處及改善
- 本方案首要的不足在于前端無法準確獲知資料庫中資料的更新時間,目前暫時設定了快取時間
expires = 3600 * 1000 ms,也就是說1h內資料被更新了的話,前端顯示的依然是快取的舊資料,這一點暫時沒想到改善方法, - 此外,快取使用了
localStorage API,localStorage的特點是只要不手動清除,資料會一直保存在瀏覽器端,這樣用戶就沒有辦法清除快取,要改善這一點的話可以換一個全域物件(Vuex)來保存資料,只要頁面重繪的話,快取的資料會被清除, - 此外,在系統中會有更新這些快取相關資料的模塊,在這些模塊中,可以在更新資料之后直接進行快取資料的清除,等到下次再請求時,程式檢查到沒有快取就會直接從服務器請求新的資料,這一定程度改善了前端無法獲知資料跟新時間的不足,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/280522.html
標籤:JavaScript
上一篇:演算法學習:二分法從入門到精通
