@blocklet/payment-react
Version:
Reusable react components for payment kit v2
104 lines (85 loc) • 2.43 kB
text/typescript
import { globalCache } from './cache';
type CacheStrategy = 'session' | 'local' | 'memory';
interface CacheOptions {
strategy?: CacheStrategy;
ttl?: number; // 过期时间(毫秒)
}
export class CachedRequest {
private cacheKey: string;
private fetchData: () => Promise<any>;
private options: CacheOptions;
constructor(cacheKey: string, fetchData: () => Promise<any>, options: CacheOptions = {}) {
this.cacheKey = cacheKey;
this.fetchData = fetchData;
this.options = {
strategy: 'session',
ttl: 0,
...options,
};
}
private getCache(): any {
const { strategy } = this.options;
switch (strategy) {
case 'local':
return localStorage;
case 'memory':
return globalCache;
case 'session':
default:
return sessionStorage;
}
}
private getCachedData() {
const cache = this.getCache();
const data = this.options.strategy === 'memory' ? cache.get(this.cacheKey) : cache.getItem(this.cacheKey);
if (!data) return null;
const parsed = JSON.parse(data);
// 检查是否过期
if (this.options.ttl && parsed.timestamp) {
const isExpired = Date.now() - parsed.timestamp > this.options.ttl;
if (isExpired) {
this.clearCache();
return null;
}
}
return parsed.data;
}
private setCachedData(data: any) {
const cache = this.getCache();
const value = JSON.stringify({
data,
timestamp: Date.now(),
});
if (this.options.strategy === 'memory') {
cache.set(this.cacheKey, value);
} else {
cache.setItem(this.cacheKey, value);
}
}
clearCache() {
const cache = this.getCache();
if (this.options.strategy === 'memory') {
cache.delete(this.cacheKey);
} else {
cache.removeItem(this.cacheKey);
}
}
fetch(forceRefresh = false) {
const cachedData = !forceRefresh && this.getCachedData();
if (cachedData) return Promise.resolve(cachedData);
const globalItem = globalCache.get(this.cacheKey);
if (globalItem?.promise) {
return globalItem.promise;
}
const newPromise = this.fetchData()
.then(({ data }: any) => {
this.setCachedData(data);
return data;
})
.finally(() => {
globalCache.delete(this.cacheKey);
});
globalCache.set(this.cacheKey, { promise: newPromise });
return newPromise;
}
}