[Design Pattern] Encapsulate a network request lib - 2. Cache the request

Usage of a cached request:

const req = createCacheRequestor();
req.get('/a') // request
req.get('/a') // use cache
req.get('/b') // request
req.get('/b') // use cache

 

What we need to do is resolve following questions:

  • how to cache the request
  • where the save the cache
  • what is the cache key

 

Cache key

Example code:

const req = createCacheRequestor({
    key: (config) {
        return config.pathname // use pathname as a key
    },
    presist: true
})

 

Design

Due to there are many ways to provide presistent feature, different approach may have different params / foramt / apis; therefore we need a stable interface for user to use.

export interface CacheStore {
    has(key: string): Promise<boolean>;
    set<T>(key: string, ...values: T[]): Promise<void>;
    get<T>()key: string): Promise<T>
    // other methods
}
    
export function useCacheStore(isPresist): CacheStore {
    if(!isPersist) {
        return createMemoryStore();
    } else {
        return createStorageStore();
    }
}

 

Cache duration

Usage:

const req = crateCacheRequestor({
    duration: 1000 * 60 * 60,
    isValild(key, config) {
       // return true means cache is valid, return false then cache is invalid
    }
})

Example code:

function createCacheRequestor(cacheOptions) {
    const options = normalizeOptions(cacheOptions);
    const store = useCacheStore(options.persist)
    const req = useRequestor()
    return req;
}

req.on('beforeRequest', async (config) => {
    const key = options.key(config);
    const hasKey = await store.has(key);
    if (hasKey && options.isValid(key, config)) {
        // return cache reuslt
    }
})

req.on('responseBody', (config, resp) => {
    const key = options.key(config)
    store.set(key, resp.toPlain());
})

 

posted @ 2024-12-01 17:32  Zhentiw  阅读(14)  评论(0)    收藏  举报