前端緩存API請求數據


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 ,首先根據 keylocalStorage 中查找緩存的時間戳(時間戳是在緩存數據時一起保存的,如果有時間戳,則表示有緩存數據),如果有緩存時間並且判斷緩存時間未過期,則進一步從緩存中獲取數據給到程序使用:

/** 獲取緩存 - 查找映射表 並 檢查過期時間 */
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 APIlocalStorage 的特點是只要不手動清除,數據會一直保存在瀏覽器端,這樣用戶就沒有辦法清除緩存,要改善這一點的話可以換一個全局對象(Vuex)來保存數據,只要頁面刷新的話,緩存的數據會被清除。
  • 此外,在系統中會有更新這些緩存相關數據的模塊,在這些模塊中,可以在更新數據之后直接進行緩存數據的清除,等到下次再請求時,程序檢查到沒有緩存就會直接從服務器請求新的數據,這一定程度改善了前端無法獲知數據跟新時間的不足。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM