<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端緩存API請求數(shù)據(jù)的解決方案

          共 2663字,需瀏覽 6分鐘

           ·

          2021-05-06 17:49

          來源 | https://www.cnblogs.com/yuanyiming/p/14706224.html


          1、背景

          在一些項目中,有時候會出現(xiàn)不同模塊重復請求大量相同API接口的情況,特別是在一些功能相似的后臺管理頁面中。
          以下面這幾個頁面為例,每次進入頁面都需要請求等大量重復的下拉框數(shù)據(jù),下拉框數(shù)據(jù)短時間內(nèi)改動不大,但也不能在前端使用靜態(tài)數(shù)據(jù),所以可以考慮在前端進行數(shù)據(jù)緩存,避免重復請求API。

          2、 實現(xiàn)思路

          主要有以下3個步驟:
          • 初次獲取數(shù)據(jù),從服務器中請求數(shù)據(jù);

          • 建立一個映射表,將下拉框數(shù)據(jù)保存起來,并同時記錄該數(shù)據(jù)的時間戳;

          • 后續(xù)再次請求時,首先從映射表中查找數(shù)據(jù),如果可以查到數(shù)據(jù)且數(shù)據(jù)沒過期,則直接使用數(shù)據(jù),否則重新從服務器中獲取數(shù)據(jù);

          3、具體實現(xiàn)

          3.1 、初次獲取數(shù)據(jù)

          以下代碼中,首先調(diào)用 getLocalData 方法查找緩存,如果沒找到緩存,就向服務器請求數(shù)據(jù)(this.$api.task.getCateListAll),獲取到數(shù)據(jù)后用 setLocalData 方法把數(shù)據(jù)緩存起來。
          // 任務類型下拉框數(shù)據(jù)// 首先判斷是否有緩存if (!this.getLocalData('cate')) {  /** 初次請求數(shù)據(jù) */  await this.$api.task.getCateListAll().then((res) => {    this.m_taskPropOption.cate = this.$u.array.arrToSelect(res.data); // 使用數(shù)據(jù)    this.m_taskPropDict.cate = this.$u.array.arrToObj(this.m_taskPropOption.cate, "id"); // 使用數(shù)據(jù)    this.setLocalData('cate'); // 緩存數(shù)據(jù)  });}

          3.2 、建立映射表,緩存數(shù)據(jù)

          緩存數(shù)據(jù)主要使用了瀏覽器的API localStorage,如下面代碼中 setLocalData 方法,每次從服務器獲取數(shù)據(jù)后,根據(jù) key 將數(shù)據(jù)保存在 localStorage 中,并且同時記錄時間戳,記錄時間戳是為了后面檢查緩存數(shù)據(jù)的過期時間:

          /** 設(shè)置緩存 - 建立映射表 */setLocalData(key) {  // 緩存數(shù)據(jù)  localStorage.setItem(`task_${key}_option`, jsON.stringify(this.m_taskPropOption[key])); // 緩存數(shù)據(jù)  localStorage.setItem(`task_${key}_dict`, jsON.stringify(this.m_taskPropDict[key])); // 緩存數(shù)據(jù)  localStorage.setItem(`task_${key}_timestamp`, Date.now()); // 記錄時間戳}

          3.3 、查找緩存數(shù)據(jù)

          根據(jù)方法 getLocalData ,首先根據(jù) key 從 localStorage 中查找緩存的時間戳(時間戳是在緩存數(shù)據(jù)時一起保存的,如果有時間戳,則表示有緩存數(shù)據(jù)),如果有緩存時間并且判斷緩存時間未過期,則進一步從緩存中獲取數(shù)據(jù)給到程序使用:

          /** 獲取緩存 - 查找映射表 并 檢查過期時間 */getLocalData(key) {  let storageTimestamp = localStorage.getItem(`task_${key}_timestamp`);  let expires = 1000 * 3600; // 有效時間  let timestamp = Date.now();  // 當前時間戳  // 從緩存中取數(shù)據(jù)(1h內(nèi)數(shù)據(jù))  if (storageTimestamp && (timestamp - storageTimestamp) < expires) {    let option = localStorage.getItem(`task_${key}_option`); // 從緩存中拿到數(shù)據(jù)給程序使用    let dict = localStorage.getItem(`task_${key}_dict`); // 從緩存中拿到數(shù)據(jù)給程序使用    this.m_taskPropOption[key] = JSON.parse(option);    this.m_taskPropDict[key] = JSON.parse(dict);    return true;  }  return false;}

          3.4 、實現(xiàn)效果

          使用緩存前進入頁面:

          使用緩存后進入頁面:

          由上圖可以看出,使用緩存前進入頁面需要請求7個api接口,而緩存了數(shù)據(jù)之后,進入頁面只需要請求3個接口即可,確實起到了減少了請求接口數(shù)量的效果。

          4、方案的不足之處及改善

          本方案首要的不足在于前端無法準確獲知數(shù)據(jù)庫中數(shù)據(jù)的更新時間。目前暫時設(shè)置了緩存時間 expires = 3600 * 1000 ms,也就是說1h內(nèi)數(shù)據(jù)被更新了的話,前端顯示的依然是緩存的舊數(shù)據(jù),這一點暫時沒想到改善方法。

          此外,緩存使用了 localStorage API。localStorage 的特點是只要不手動清除,數(shù)據(jù)會一直保存在瀏覽器端,這樣用戶就沒有辦法清除緩存,要改善這一點的話可以換一個全局對象(vuex)來保存數(shù)據(jù),只要頁面刷新的話,緩存的數(shù)據(jù)會被清除。

          此外,在系統(tǒng)中會有更新這些緩存相關(guān)數(shù)據(jù)的模塊,在這些模塊中,可以在更新數(shù)據(jù)之后直接進行緩存數(shù)據(jù)的清除,等到下次再請求時,程序檢查到?jīng)]有緩存就會直接從服務器請求新的數(shù)據(jù),這一定程度改善了前端無法獲知數(shù)據(jù)跟新時間的不足。


          學習更多技能

          請點擊下方公眾號


          瀏覽 47
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级片黄色电影免费 | 黑人操欧美人 | 日韩国产精品毛片 | 国产无码一区二区三区 | 午夜中文无码520 |