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

