Redis使用LocalStorage的實(shí)現(xiàn)示例
參考 Redis 緩存接口封裝 LocalStorage,在全棧項(xiàng)目中保持一致的緩存操作體驗(yàn),降低前端同學(xué)轉(zhuǎn)向全棧開發(fā)的心智負(fù)擔(dān)
1. 為什么需要 Redis 風(fēng)格的 LocalStorage 封裝
在全棧開發(fā)中,后端通常使用 Redis 進(jìn)行緩存管理,而前端則使用 LocalStorage 存儲(chǔ)本地?cái)?shù)據(jù)。兩者的 API 接口差異較大,這給從前端轉(zhuǎn)向全棧的開發(fā)者帶來了額外的學(xué)習(xí)成本。
通過封裝一個(gè) Redis 風(fēng)格的 LocalStorage 工具類,我們可以:
- 保持前后端緩存操作接口一致
- 提供更豐富的緩存管理功能(如過期時(shí)間、鍵匹配等)
- 增強(qiáng)代碼的可維護(hù)性和可讀性
- 為未來可能的后端遷移做好準(zhǔn)備
2. 核心功能實(shí)現(xiàn)與代碼解析
完整工具類實(shí)現(xiàn)
export abstract class CacheUtil {
/**
* 設(shè)置緩存
* @param key 緩存鍵
* @param value 緩存值
* @param ttl 過期時(shí)間(單位:秒),-1 表示永不過期
*/
static set(key: string, value: any, ttl: number = -1) {
const data = { value, ttl: ttl === -1 ? ttl : Date.now() + ttl * 1000 }
localStorage.setItem(key, JSON.stringify(data))
}
/**
* 獲取緩存
* @param key 緩存鍵
* @param defaultValue 緩存不存在或過期時(shí)的默認(rèn)值
* @returns 緩存值或默認(rèn)值
*/
static get<T = any>(key: string, defaultValue: T | null = null): T | null {
try {
const jsonStr = localStorage.getItem(key)
if (!jsonStr) return defaultValue
const data = JSON.parse(jsonStr)
if (data.ttl === -1 || Date.now() <= data.ttl) return data.value
localStorage.removeItem(key)
return defaultValue
} catch (error: unknown) {
localStorage.removeItem(key)
return defaultValue
}
}
/**
* 獲取緩存剩余過期時(shí)間(秒)
* -1 = 永久有效
* -2 = 已過期/不存在
*/
static ttl(key: string): number {
try {
const item = localStorage.getItem(key)
if (!item) return -2
const data = JSON.parse(item)
if (data.ttl === -1) return -1
const remaining = data.ttl - Date.now()
return remaining > 0 ? Math.floor(remaining / 1000) : -2
} catch {
return -2 // 解析失敗,視為無效緩存
}
}
/**
* 動(dòng)態(tài)設(shè)置緩存過期時(shí)間
* @param key 緩存鍵
* @param ttl 過期時(shí)間(秒)
* @returns 是否設(shè)置成功
*/
static expire(key: string, ttl: number): boolean {
const value = this.get(key)
if (value === null) return false
this.set(key, value, ttl)
return true
}
/**
* 刪除緩存
* @param key 緩存鍵
*/
static del(key: string) {
localStorage.removeItem(key)
}
/**
* 清空所有緩存
*/
static flushall() {
localStorage.clear()
}
/**
* 查找緩存鍵(支持通配符 *,和 Redis 用法一致)
* @param pattern 匹配規(guī)則,例如 user*、*info、*token*,默認(rèn) *
* @returns 匹配的鍵數(shù)組
*/
static keys(pattern: string = '*'): string[] {
const allKeys = Object.keys(localStorage)
const regex = new RegExp(pattern.replace(/\*/g, '.*'))
return allKeys.filter((key) => regex.test(key))
}
/**
* 檢查緩存是否存在且未過期
* @param key 緩存鍵
* @returns 是否存在有效緩存
*/
static exists(key: string): boolean {
return this.get(key) !== null
}
}核心設(shè)計(jì)要點(diǎn)
數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì):使用
{ value, ttl }結(jié)構(gòu)存儲(chǔ)緩存數(shù)據(jù),其中ttl為過期時(shí)間戳或 -1(永不過期)過期時(shí)間處理:
- 設(shè)置時(shí)計(jì)算絕對(duì)過期時(shí)間戳
- 獲取時(shí)檢查是否過期,過期則自動(dòng)清理
- 提供
ttl方法查看剩余過期時(shí)間
錯(cuò)誤處理:通過 try-catch 捕獲 JSON 解析異常,確保緩存操作的穩(wěn)定性
Redis 風(fēng)格 API:實(shí)現(xiàn)了與 Redis 相似的
set、get、del、expire、keys、exists等方法通配符支持:
keys方法支持*通配符匹配,與 Redis 用法一致
3. 完整 API 接口說明
| 方法 | 功能描述 | 參數(shù)說明 | 返回值 |
|---|---|---|---|
| set(key, value, ttl) | 設(shè)置緩存 | key: 緩存鍵 value: 緩存值 ttl: 過期時(shí)間(秒),默認(rèn) -1 | 無 |
| get(key, defaultValue) | 獲取緩存 | key: 緩存鍵 defaultValue: 默認(rèn)值,默認(rèn) null | 緩存值或默認(rèn)值 |
| ttl(key) | 獲取剩余過期時(shí)間 | key: 緩存鍵 | -1: 永久有效 -2: 已過期/不存在 正數(shù): 剩余秒數(shù) |
| expire(key, ttl) | 設(shè)置過期時(shí)間 | key: 緩存鍵 ttl: 過期時(shí)間(秒) | 是否設(shè)置成功 |
| del(key) | 刪除緩存 | key: 緩存鍵 | 無 |
| flushall() | 清空所有緩存 | 無 | 無 |
| keys(pattern) | 查找匹配的鍵 | pattern: 匹配規(guī)則,默認(rèn) * | 匹配的鍵數(shù)組 |
| exists(key) | 檢查緩存是否存在 | key: 緩存鍵 | 是否存在有效緩存 |
4. 實(shí)戰(zhàn)使用示例
基礎(chǔ)操作
// 設(shè)置緩存,1小時(shí)過期
CacheUtil.set('USER', { id: 1, name: 'John' }, 3600)
// 獲取緩存
const user = CacheUtil.get('USER')
console.log(user) // { id: 1, name: 'John' }過期時(shí)間管理
// 續(xù)期緩存,設(shè)置為2小時(shí)過期
CacheUtil.expire('USER', 7200)
// 查看剩余過期時(shí)間
const remainingTime = CacheUtil.ttl('USER')
console.log(`剩余過期時(shí)間:${remainingTime}秒`)鍵管理
// 通配符查找鍵
const userKeys = CacheUtil.keys('USER*')
const infoKeys = CacheUtil.keys('*INFO')
console.log('用戶相關(guān)鍵:', userKeys)
console.log('信息相關(guān)鍵:', infoKeys)
// 檢查緩存是否存在
const exists = CacheUtil.exists('USER')
console.log('USER 緩存存在:', exists)刪除操作
// 刪除指定緩存
CacheUtil.del('USER')
// 清空所有緩存
CacheUtil.flushall()5. 性能考量與最佳實(shí)踐
性能考量
- 存儲(chǔ)限制:LocalStorage 通常有 5MB 左右的存儲(chǔ)限制,避免存儲(chǔ)過大的數(shù)據(jù)
- 讀取性能:頻繁讀取大對(duì)象會(huì)影響性能,建議將數(shù)據(jù)合理拆分
- 過期檢查:每次
get操作都會(huì)檢查過期時(shí)間,對(duì)性能影響較小但需注意 - JSON 序列化:復(fù)雜對(duì)象的序列化/反序列化會(huì)有性能開銷,建議存儲(chǔ)結(jié)構(gòu)盡量簡單
最佳實(shí)踐
- 命名規(guī)范:使用統(tǒng)一的命名前綴(如
APP_)避免鍵名沖突 - 數(shù)據(jù)類型:只存儲(chǔ)必要的數(shù)據(jù),避免存儲(chǔ)整個(gè)應(yīng)用狀態(tài)
- 過期策略:為臨時(shí)數(shù)據(jù)設(shè)置合理的過期時(shí)間,避免占用存儲(chǔ)空間
- 錯(cuò)誤處理:雖然工具類已做了錯(cuò)誤處理,但調(diào)用時(shí)仍需考慮異常情況
- 安全注意:不要存儲(chǔ)敏感信息(如密碼、Token)到 LocalStorage
到此這篇關(guān)于Redis使用LocalStorage的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Redis LocalStorage內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于SpringBoot 使用 Redis 分布式鎖解決并發(fā)問題
針對(duì)上面問題,一般的解決方案是使用分布式鎖來解決,本文通過場景分析給大家介紹關(guān)于SpringBoot 使用 Redis 分布式鎖解決并發(fā)問題,感興趣的朋友一起看看吧2021-11-11
Redis實(shí)現(xiàn)Session共享與單點(diǎn)登錄
本文主要介紹了Redis實(shí)現(xiàn)Session共享與單點(diǎn)登錄,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
redis5.0以上基于密碼認(rèn)證的集群cluster方式
這篇文章主要介紹了redis5.0以上基于密碼認(rèn)證的集群cluster方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11

