日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Axios 如何缓存请求数据?

發(fā)布時間:2023/12/9 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Axios 如何缓存请求数据? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

大家好,我是若川。歡迎加我微信?ruochuan12,長期交流學(xué)習(xí)。今天推薦這篇Axios緩存請求數(shù)據(jù)的文章,相信是常見的業(yè)務(wù)場景,感興趣的讀者可以看看 umi-request,支持緩存功能。另外我之前也寫過 axios源碼文章,是轉(zhuǎn)載次數(shù)(16次)最多的一篇文章,好久沒寫好文章了,慚愧慚愧。

點(diǎn)擊下方卡片關(guān)注我,或者查看源碼等系列文章。學(xué)習(xí)源碼整體架構(gòu)系列、年度總結(jié)、JS基礎(chǔ)系列

在 Axios 如何取消重復(fù)請求? 這篇文章中,阿寶哥介紹了在 Axios 中如何取消重復(fù)請求及 CancelToken 的工作原理。本文將介紹在 Axios 中如何通過增強(qiáng)默認(rèn)適配器來緩存請求數(shù)據(jù)。那么為什么要緩存請求數(shù)據(jù)呢?這是因為在緩存未失效時,我們可以直接使用已緩存的數(shù)據(jù),而不需發(fā)起請求從服務(wù)端獲取數(shù)據(jù),這樣不僅可以減少 HTTP 請求而且還能減少等待時間從而提高用戶體驗。

因為本文將使用 Axios 提供的默認(rèn)適配器來實現(xiàn)緩存請求數(shù)據(jù)的功能,所以如果你對 Axios 適配器還不熟悉的話,建議先閱讀 77.9K 的 Axios 項目有哪些值得借鑒的地方 這篇文章。為了讓大家能夠更好地理解后續(xù)的內(nèi)容,我們先來看一下整體的流程圖:

上圖中藍(lán)色部分的工作流程,就是本文的重點(diǎn)。接下來,阿寶哥將從如何設(shè)計緩存開始,帶大家一起來開發(fā)緩存請求數(shù)據(jù)的功能。

一、如何設(shè)計緩存

在計算中,緩存是一個高速數(shù)據(jù)存儲層,其中存儲了數(shù)據(jù)子集,且通常是 短暫性 存儲,這樣日后再次請求該數(shù)據(jù)時,速度要比訪問數(shù)據(jù)的主存儲位置快。通過緩存,你可以高效地重用之前檢索或計算的數(shù)據(jù)。了解完緩存的作用之后,我們來設(shè)計緩存的 API:

  • get(key):從緩存中獲取指定 key 對應(yīng)的值;

  • delete(key):從緩存中刪除指定 key 對應(yīng)的值;

  • clear():清空已緩存的數(shù)據(jù);

  • set(key, value, maxAge):保存鍵值對,同時支持設(shè)置緩存的最大時間,即 maxAge 單位為毫秒。

基于上述的緩存 API,我們可以實現(xiàn)一個簡單的緩存功能,具體代碼如下所示:

const?MemoryCache?=?{data:?{},set(key,?value,?maxAge)?{?//?保存數(shù)據(jù)this.data[key]?=?{maxAge:?maxAge?||?0,value,now:?Date.now(),};},get(key)?{?//?從緩存中獲取指定 key 對應(yīng)的值。const?cachedItem?=?this.data[key];if?(!cachedItem)?return?null;const?isExpired?=?Date.now()?-?cachedItem.now?>?cachedItem.maxAge;isExpired?&&?this.delete(key);return?isExpired???null?:?cachedItem.value;},delete(key)?{?//?從緩存中刪除指定 key 對應(yīng)的值。return?delete?this.data[key];},clear()?{?//?清空已緩存的數(shù)據(jù)。this.data?=?{};}, };

其實除了自定義緩存對象之外,你也可以使用成熟的第三方庫,比如 lru-cache。

LRU 緩存淘汰算法就是一種常用策略。LRU 的全稱是 Least Recently Used,也就是說我們認(rèn)為最近使用過的數(shù)據(jù)應(yīng)該是是「有用的」,很久都沒用過的數(shù)據(jù)應(yīng)該是無用的,內(nèi)存滿了就優(yōu)先刪那些很久沒用過的數(shù)據(jù)。

二、如何增強(qiáng)默認(rèn)適配器

Axios 引入了適配器,使得它可以同時支持瀏覽器和 Node.js 環(huán)境。對于瀏覽器環(huán)境來說,它通過封裝 XMLHttpRequest API 來發(fā)送 HTTP 請求,而對于 Node.js 環(huán)境來說,它通過封裝 Node.js 內(nèi)置的 http?和?https 模塊來發(fā)送 HTTP 請求。

在介紹如何增強(qiáng)默認(rèn)適配器之前,我們先來回顧一下 Axios 完整請求的流程:

了解完 Axios 完整請求的流程之后,我們再來看一下 Axios 內(nèi)置的 xhrAdapter 適配器,它被定義在 lib/adapters/xhr.js 文件中:

//?lib/adapters/xhr.js module.exports?=?function?xhrAdapter(config)?{return?new?Promise(function?dispatchXhrRequest(resolve,?reject)?{var?requestData?=?config.data;var?requestHeaders?=?config.headers;var?request?=?new?XMLHttpRequest();//?省略大部分代碼var?fullPath?=?buildFullPath(config.baseURL,?config.url);request.open(config.method.toUpperCase(),?buildURL(fullPath,?config.params,?config.paramsSerializer),?true);//?Set?the?request?timeout?in?MSrequest.timeout?=?config.timeout;//?Listen?for?ready?staterequest.onreadystatechange?=?function?handleLoad()?{?...?}//?Send?the?requestrequest.send(requestData);}); };

很明顯 xhrAdapter 適配器是一個函數(shù)對象,它接收一個 config 參數(shù)并返回一個 Promise 對象。而在 xhrAdapter 適配器內(nèi)部,最終會使用 XMLHttpRequest API 來發(fā)送 HTTP 請求。為了實現(xiàn)緩存請求數(shù)據(jù)的功能,我們就可以考慮通過高階函數(shù)來增強(qiáng) xhrAdapter 適配器的功能。

2.1 定義輔助函數(shù)

2.1.1 定義 generateReqKey 函數(shù)

在增強(qiáng) xhrAdapter 適配器之前,我們先來定義一個 generateReqKey 函數(shù),該函數(shù)用于根據(jù)當(dāng)前請求的信息,生成請求 Key;

function?generateReqKey(config)?{const?{?method,?url,?params,?data?}?=?config;return?[method,?url,?Qs.stringify(params),?Qs.stringify(data)].join("&"); }

通過 generateReqKey 函數(shù)生成的請求 key,將作為緩存項的 key,而對應(yīng)的 value 就是默認(rèn) xhrAdapter 適配器返回的 Promise 對象。

2.1.2 定義 isCacheLike 函數(shù)

isCacheLike 函數(shù)用于判斷傳入的 cache 參數(shù)是否實現(xiàn)了前面定義的 Cache API,利用該函數(shù),我們允許用戶為每個請求自定義 Cache 對象。

function?isCacheLike(cache)?{return?!!(cache.set?&&?cache.get?&&?cache.delete?&&?cache.clear??&&?typeof?cache.get?===?'function'?&&?typeof?cache.set?===?'function'?&&?typeof?cache.delete?===?'function'?&&?typeof?cache.clear?===?'function'); }

2.2 定義 cacheAdapterEnhancer 函數(shù)

為了讓用戶能夠更靈活地控制數(shù)據(jù)緩存的功能,我們定義了一個 cacheAdapterEnhancer 函數(shù),該函數(shù)支持兩個參數(shù):

  • adapter:預(yù)增強(qiáng)的 Axios 適配器對象;

  • options:緩存配置對象,該對象支持 4 個屬性,分別用于配置不同的功能:

    • maxAge:全局設(shè)置緩存的最大時間;

    • enabledByDefault:是否啟用緩存,默認(rèn)為 true;

    • cacheFlag:緩存標(biāo)志,用于配置請求 config 對象上的緩存屬性;

    • defaultCache:用于設(shè)置使用的緩存對象。

了解完 cacheAdapterEnhancer 函數(shù)的參數(shù)之后,我們來看一下該函數(shù)的具體實現(xiàn):

function?cacheAdapterEnhancer(adapter,?options)?{const?{?maxAge,?enabledByDefault?=?true,cacheFlag?=?"cache",?defaultCache?=?MemoryCache,}?=?options;return?(config)?=>?{const?{?url,?method,?params,?forceUpdate?}?=?config;let?useCache?=?config[cacheFlag]?!==?undefined?&&?config[cacheFlag]?!==?null??config[cacheFlag]:?enabledByDefault;if?(method?===?"get"?&&?useCache)?{const?cache?=?isCacheLike(useCache)???useCache?:?defaultCache;let?requestKey?=?generateReqKey(config);??//?生成請求Keylet?responsePromise?=?cache.get(requestKey);?//?從緩存中獲取請求key對應(yīng)的響應(yīng)對象if?(!responsePromise?||?forceUpdate)?{?//?緩存未命中/失效或強(qiáng)制更新時,則重新請求數(shù)據(jù)responsePromise?=?(async?()?=>?{try?{return?await?adapter(config);??//?使用默認(rèn)的xhrAdapter發(fā)送請求}?catch?(reason)?{cache.delete(requestKey);throw?reason;}})();cache.set(requestKey,?responsePromise,?maxAge);??//?保存請求返回的響應(yīng)對象return?responsePromise;?//?返回已保存的響應(yīng)對象}return?responsePromise;}return?adapter(config);?//?使用默認(rèn)的xhrAdapter發(fā)送請求}; }

以上的代碼并不會復(fù)雜,核心的處理邏輯如下圖所示:

2.3 使用 cacheAdapterEnhancer 函數(shù)

2.3.1 創(chuàng)建 Axios 對象并配置 adapter 選項
const?http?=?axios.create({baseURL:?"https://jsonplaceholder.typicode.com",adapter:?cacheAdapterEnhancer(axios.defaults.adapter,?{enabledByDefault:?false,?//?默認(rèn)禁用緩存maxAge:?5000,?//?緩存時間為5s}), });
2.3.2 使用 http 對象發(fā)送請求
//?使用緩存 async?function?requestWithCache()?{const?response?=?await?http.get("/todos/1",?{?cache:?true?});console.dir(response); }//?不使用緩存 async?function?requestWithoutCache()?{const?response?=?await?http.get("/todos/1",?{?cache:?false?});console.dir(response); }

其實 cache 屬性除了支持布爾值之外,我們可以配置實現(xiàn) Cache API 的緩存對象,具體的使用示例如下所示:

const?customCache?=?{?get()?{/*...*/},?set()?{/*...*/},?delete()?{/*...*/},?clear()?{/*...*/}};async?function?requestForceUpdate()?{const?response?=?await?http.get("/todos/1",?{cache:?customCache,forceUpdate:?true,});console.dir(response); }

好了,如何通過增強(qiáng) xhrAdapter 適配器來實現(xiàn) Axios 緩存請求數(shù)據(jù)的功能已經(jīng)介紹完了。由于完整的示例代碼內(nèi)容比較多,阿寶哥就不放具體的代碼了。感興趣的小伙伴,可以訪問以下地址瀏覽示例代碼。

完整的示例代碼:https://gist.github.com/semlinker/b8a7bd5a0a16c2d04011c2c4a8167fbd

三、總結(jié)

本文介紹了在 Axios 中如何緩存請求數(shù)據(jù)及如何設(shè)計緩存對象,基于文中定義的 cacheAdapterEnhancer 函數(shù),你可以輕松地擴(kuò)展緩存的功能。在后續(xù)的文章中,阿寶哥將會介紹在 Axios 中如何實現(xiàn)請求重試功能,感興趣的小伙伴不要錯過喲。另外,如果你對 Axios 如何取消重復(fù)請求感興趣,可以閱讀 Axios 如何取消重復(fù)請求? 這篇文章。

四、參考資源

  • 77.9K 的 Axios 項目有哪些值得借鑒的地方

  • Axios 如何取消重復(fù)請求?

  • Github - axios-extensions


最近組建了一個江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你進(jìn)群。


·················?若川出品?·················

今日話題

建的江西前端交流群,感覺氛圍不錯,想著要不要建其他省份的交流群,不過我是江西人,建其他省份的會不會有人進(jìn)群是個問題~。歡迎分享、收藏、點(diǎn)贊、在看我的公眾號文章~

一個愿景是幫助5年內(nèi)前端人走向前列的公眾號

可加我個人微信 ruochuan12,長期交流學(xué)習(xí)

推薦閱讀

我在阿里招前端,我該怎么幫你?(現(xiàn)在還能加我進(jìn)模擬面試群)

如何拿下阿里巴巴 P6 的前端 Offer

點(diǎn)擊方卡片關(guān)注我,或者查看源碼等系列文章。
學(xué)習(xí)源碼整體架構(gòu)系列、年度總結(jié)、JS基礎(chǔ)系列

總結(jié)

以上是生活随笔為你收集整理的Axios 如何缓存请求数据?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。