如何巧用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è)常用場景,比如存在一個(gè)數(shù)組,需要把每個(gè)元素的首字母轉(zhuǎn)為大寫。
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ù)開發(fā)中存在這么一個(gè)場景,輸入框搜索。當(dāng)輸入框觸發(fā)input事件的時(shí)候,我們都會(huì)調(diào)用接口返回查詢結(jié)果。比如我輸入了掘金關(guān)鍵字返回了結(jié)果,然后又輸入掘金NBA返回了結(jié)果,此時(shí)我刪掉了NBA,又查詢掘金, 實(shí)際上這個(gè)結(jié)果我們之前查過,如果緩存起來直接拉緩存即可,不用再去調(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));
};
};
使用場景
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ì)上面的場景,雖然el-input底層已經(jīng)使用compositionEnd和compositionStart事件來做一層防抖,只有文字真正輸入到屏幕上才會(huì)去觸發(fā)input事件。但是這是不夠,如果用戶輸入手速很快,會(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是全局注入,基本使用原先的類名進(jìn)行二次創(chuàng)建公共組件,修改基礎(chǔ)js實(shí)現(xiàn)邏輯,本文結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問題
這篇文章主要介紹了postcss-pxtorem設(shè)置不轉(zhuǎn)換UI框架的CSS單位問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
vue3響應(yīng)式Object代理對(duì)象的讀取示例詳解
這篇文章主要為大家介紹了vue3響應(yīng)式Object代理對(duì)象的讀取示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Nuxt封裝@nuxtjs/axios請(qǐng)求后端數(shù)據(jù)方式
這篇文章主要介紹了Nuxt封裝@nuxtjs/axios請(qǐng)求后端數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10

