如何巧用Vue緩存函數(shù)淺析
vue2中的緩存函數(shù)
vue2版本中有這么一個(gè)緩存函數(shù)
/** * Create a cached version of a pure function. */ function cached (fn) { var cache = Object.create(null); return (function cachedFn (str) { var hit = cache[str]; return hit || (cache[str] = fn(str)) }) }
上面這個(gè)函數(shù)存在一個(gè)常用場(chǎng)景,比如存在一個(gè)數(shù)組,需要把每個(gè)元素的首字母轉(zhuǎn)為大寫(xiě)。
const array = ['abc', 'ed', 'abc', 'acd', 'ed', 'fkg', ...];
常用的解決方法
// 定一個(gè)capitalize函數(shù) function capitalize (str) { return str.charAt(0).toUpperCase() + str.slice(1) }; const capitalizeArray = array.map(capitalize);
細(xì)心的我們會(huì)發(fā)現(xiàn)array中存在不少重復(fù)的元素, 他們返回的結(jié)果一樣的,實(shí)際不需要重復(fù)計(jì)算執(zhí)行capitalize,而且capitalize是一個(gè)PURE函數(shù),此時(shí)我們可以利用上面的cached做一個(gè)備忘錄的功能。
改造如下
function capitalize (str) { return str.charAt(0).toUpperCase() + str.slice(1) }; const capitalizeArray = array.map(cached(capitalize));
當(dāng)遇到重復(fù)字符串的時(shí)候會(huì)直接返回緩存的結(jié)果。想想capitalize是一個(gè)十分耗時(shí)的任務(wù),性能優(yōu)化不止一點(diǎn)點(diǎn)。
改造vue緩存函數(shù)
上面的舉例是緩存同步任務(wù)的純函數(shù),在業(yè)務(wù)開(kāi)發(fā)中存在這么一個(gè)場(chǎng)景,輸入框搜索。當(dāng)輸入框觸發(fā)input事件的時(shí)候,我們都會(huì)調(diào)用接口返回查詢(xún)結(jié)果。比如我輸入了掘金關(guān)鍵字返回了結(jié)果,然后又輸入掘金NBA返回了結(jié)果,此時(shí)我刪掉了NBA,又查詢(xún)掘金, 實(shí)際上這個(gè)結(jié)果我們之前查過(guò),如果緩存起來(lái)直接拉緩存即可,不用再去調(diào)用接口。
我們基于cached實(shí)現(xiàn)一個(gè)緩存異步純函數(shù)的備忘錄
const cachedAsync = function(fn) { const cache = Object.create(null); return async str => { const hit = cache[str]; if (hit) { return hit; } // 只緩存成功的Promise, 失敗直接重新請(qǐng)求 return (cache[str] = await fn(str)); }; };
使用場(chǎng)景
const cachedAsyncQueryPrdList = cachedAsync(prdNo => { // 下面是一個(gè)請(qǐng)求的操作,返回一個(gè)promise return queryPrdList({ prdNo }); }); <template> <el-input v-model="prdNo" placeholder="請(qǐng)輸入產(chǎn)品編碼" @input="handleQueryPrdList" /> <el-select> <el-option v-for="item in prdList" :label="item.label" :value="item.value"> </el-select> </template> <script> export default { data() { prdNo: '', prdList: [], }, methods: { async handleQueryPrdList() { const { data } = await cachedAsyncQueryPrdList(this.prdNo); this.prdList = data; } } } </script>
上面實(shí)現(xiàn)了,當(dāng)輸入相同的關(guān)鍵字,如果之前請(qǐng)求是成功的,直接拉起緩存,不會(huì)重新向服務(wù)器發(fā)起請(qǐng)求。因?yàn)槲覀兊膫渫浿粫?huì)緩存成功的promise。
優(yōu)化
針對(duì)上面的場(chǎng)景,雖然el-input底層已經(jīng)使用compositionEnd和compositionStart事件來(lái)做一層防抖,只有文字真正輸入到屏幕上才會(huì)去觸發(fā)input事件。但是這是不夠,如果用戶(hù)輸入手速很快,會(huì)出現(xiàn)一秒發(fā)幾次請(qǐng)求的情況,增加了服務(wù)器負(fù)擔(dān)。因此這種一般會(huì)搭配防抖函數(shù)使用。
防抖函數(shù)
const debounce = (fn, ms = 300) => { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => fn.apply(this, args), ms); }; };
然后搭配我們的cachedAsync使用
const cachedAsyncQueryPrdList = cachedAsync(prdNo => { // 下面是一個(gè)ajax請(qǐng)求的操作,返回一個(gè)promise return queryPrdList({ prdNo }); }); <template> <el-input v-model="prdNo" placeholder="請(qǐng)輸入產(chǎn)品編碼" @input="debounceQueryPrdListFn" /> <el-select> <el-option v-for="item in prdList" :label="item.label" :value="item.value"> </el-select> </template> <script> const noop = () => {}; export default { data() { prdNo: '', prdList: [], debounceQueryPrdListFn: noop, }, created() { this.debounceQueryPrdListFn = debounce(this.handleQueryPrdList); }, methods: { async handleQueryPrdList() { const { data } = await cachedAsyncQueryPrdList(this.prdNo); this.prdList = data; } } } </script>
FBI WARNING: >>> cachedAsync函數(shù),只適用于PURE函數(shù)。
這個(gè)實(shí)現(xiàn)已經(jīng)在生產(chǎn)環(huán)境穩(wěn)定使用,大家可以放心食用。
總結(jié)
到此這篇關(guān)于如何巧用Vue緩存函數(shù)的文章就介紹到這了,更多相關(guān)巧用Vue緩存函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue自定義穿梭框支持遠(yuǎn)程滾動(dòng)加載的實(shí)現(xiàn)方法
這篇文章主要介紹了vue自定義穿梭框支持遠(yuǎn)程滾動(dòng)加載,iview是全局注入,基本使用原先的類(lèi)名進(jìn)行二次創(chuàng)建公共組件,修改基礎(chǔ)js實(shí)現(xiàn)邏輯,本文結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問(wèn)題
這篇文章主要介紹了postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07vue3響應(yīng)式Object代理對(duì)象的讀取示例詳解
這篇文章主要為大家介紹了vue3響應(yīng)式Object代理對(duì)象的讀取示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08vue項(xiàng)目依賴(lài)檢查depcheck問(wèn)題
這篇文章主要介紹了vue項(xiàng)目依賴(lài)檢查depcheck問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07Nuxt封裝@nuxtjs/axios請(qǐng)求后端數(shù)據(jù)方式
這篇文章主要介紹了Nuxt封裝@nuxtjs/axios請(qǐng)求后端數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10