我想要通過 JS 實現全局單例的對象緩存,但似乎都沒有很好的解決辦法。
目前環境:node + vue 瀏覽器端運行
let cache = [];
async function getUser(id){
return new Promise((resolve) => {
if(Object.prototype.hasOwnProperty.call(cache, id)){
return resolve(cache[id])
}
setTimeout(() => {
const obj = {
id:id,
name:Math.random() .toString(36)
}
cache[id] = obj
resolve(obj)
}, 200);
})
}
如,上面代碼是通過ID獲取一個用戶對象,而這個用戶對象本想緩存起來,反復利用。其中的setTimeout是表示從網絡資源獲取或者是從數據庫獲取都將會是異步操作反饋。
> getUser(1).then(data=>console.log(data))
getUser(1).then(data=>console.log(data))
getUser(1).then(data=>console.log(data))
< Promise {<pending>}
VM323:1 {id: 1, name: "0.gayf057xhjo"}
VM323:2 {id: 1, name: "0.owi31fi79z"}
VM323:3 {id: 1, name: "0.3bya3r4poxn"}
如果連續執行多次,就會產生多個"用戶對象", 通過名字鑒別,是因為緩存還未寫入,導致后面的函數也會進入重新獲取對象產生"新對象",前者先執行完畢寫入的緩存對象也會被后來者覆蓋,這是不被允許的。
如果之后再次獲取,命中緩存了,獲取到最后一次存儲的緩存對象,前幾次冗余的就會失效。
問題:
這個邏輯中,我想解決唯一緩存對象,或者是異步鎖的實現,能夠有效阻塞后來者,但不丟棄。
至于為什么要一起異步并發執行,而不逐個執行,是因為實際應用場景中,可能是有多個模塊某個瞬間同時需要這塊數據造成的。
希望各位大佬幫忙看看,提供思路方法。
getUser連續運行多次,因為同步的原因,沒有走上面的if,都走了下面的定時器,2s后添加cache(此時才有的cache[id],在運行getUser才會走if里)并resolve,所以每一次都不一樣。改的話可以這么改,cache中不存放具體數據,而是存放promise實例