問(wèn)題描述:最近遇到一個(gè)問(wèn)題等缀,目前自己在做的公司項(xiàng)目中同一個(gè)頁(yè)面下,多個(gè)模塊會(huì)同時(shí)用到一個(gè)接口娇昙。導(dǎo)致在進(jìn)入頁(yè)面的時(shí)候會(huì)同時(shí)發(fā)送多個(gè)相同的請(qǐng)求尺迂。作為一個(gè)有追求的前端當(dāng)然不能忍了。
然后我就開始想解決辦法冒掌,大致方向就是通過(guò)接口緩存噪裕,在請(qǐng)求的時(shí)候檢查一下當(dāng)前進(jìn)行中的請(qǐng)求有哪些,如果有相同的就返回已存在的股毫,沒(méi)有的話就加入緩存膳音。
項(xiàng)目中的請(qǐng)求庫(kù)用的Axios.js 代碼如下
export default function zGet (url, param) {
return Axios.get(url, { params: param })
}
上面函數(shù)返回的就是Promise對(duì)象,我們要做的就是把這個(gè)對(duì)象緩存起來(lái)铃诬,放到一個(gè)數(shù)組中祭陷,然后在發(fā)請(qǐng)求時(shí)先來(lái)這里檢查下有沒(méi)有緩存苍凛,沒(méi)有就加進(jìn)去。這里主要是利用promise的一個(gè)特性兵志,無(wú)論promise處于什么狀態(tài) pending醇蝴、resolved、rejected想罕。后面都可以用then函數(shù)得到相同的結(jié)果悠栓。每個(gè)promise對(duì)象的標(biāo)識(shí)就是 path+參數(shù)
// 用來(lái)緩存Promise對(duì)象的數(shù)組
// 里面的對(duì)象格式如下
// { key: url+param, value: promise }
let promiseList = [ ]
// 檢查
function checkPromise (url,param) {
let key = url+JSON.stringify(param)
// 看看有沒(méi)有相同 Promise
let res = promiseList.filter(item => item.key === key)
// 如果有相同的進(jìn)行中的promise,直接返回
if (res.length>0) {
console.log('存在并發(fā)請(qǐng)求')
return res[0].value
// 如果沒(méi)有相同的則需要存入當(dāng)前的Promise并返回
} else {
return false
}
}
目前有個(gè)問(wèn)題就是promise對(duì)象沒(méi)有辦法直接同步的拿到當(dāng)前的狀態(tài)按价,本來(lái)打算隔段時(shí)間就把已經(jīng)完成的promise清理一下惭适,所以改成了定時(shí)清空緩存的所有promise對(duì)象。
// 每隔5分鐘清空一下promise列表楼镐,防止內(nèi)存溢出
setInterval(() => {
promiseList = []
}, 300000)
完整的代碼如下:
// 用來(lái)緩存Promise對(duì)象的數(shù)組 { key: url+param, value: promise }
let promiseList = [ ]
// 每隔5分鐘清空一下promise列表腥沽,防止內(nèi)存溢出
setInterval(() => {
promiseList = []
}, 300000)
// 檢查
function checkPromise (url,param) {
let key = url+JSON.stringify(param)
// 看看有沒(méi)有相同 Promise
let res = promiseList.filter(item => item.key === key)
// 如果有相同的進(jìn)行中的promise,直接返回
if (res.length>0) {
console.log('存在并發(fā)請(qǐng)求')
return res[0].value
// 如果沒(méi)有相同的則需要存入當(dāng)前的Promise并返回
} else {
return false
}
}
// 自己封裝的get請(qǐng)求
// 使用的時(shí)候多傳一個(gè)參數(shù)merge 表示是否使用并發(fā)合并的功能
export default function zGet (url, param, merge=false) {
// 檢查是否命中緩存中的promise如果有返回命中鸠蚪,不再發(fā)出請(qǐng)求
let cachePromise = checkPromise(url,param)
if (merge && cachePromise) {
return cachePromise
}
let promise = instance.get(url, { params: param })
promiseList.push({
key: url+JSON.stringify(param),
value: promise,
})
return promise
}
這樣就完美解決了我的問(wèn)題今阳,希望也能對(duì)大家有所幫助。