lru-cache 库不完全指南
该库提供了 lru 的具体实现,从版本7开始,这是JavaScript中性能最高的LRU实现之一,并支持多种多样的用例。
// 'max'、'ttl'、'maxSize' 三个参数必须填写至少一个
const options = {
max: 500,
}
const cache = new LRUCache(options)
cache.set('key', 'value')
cache.get('key') // "value"
class LRUCache<K, V, FC = unknown>(options)
- K, V 为 键 值 的数据类型
- FC 为 async fetch() 的接受的 context 参数类型
Options 配置
max
(只读)
缓存中保留的最大项目数量。设置最大值可以防止缓存无界增长。
ttl
元素的最大存活时间,当存活时间到时可能不会立即被删除,即使从链表中删除,可能不会立即被垃圾回收机制进行内存的回收。
maxSize
(只读)
缓存中保留的所有项目所占空间的最大值
maxEntrySize
每一项元素所占空间的最大值,超过这个大小的元素无法添加的缓存中。
sizeCalculation
用于计算所有传入的元素的大小的函数,可以覆盖掉 lru-cache 内部的计算函数。
fetchMethod(key, staleValue, { signal, options, context })
(只读)
进行异步操作,返回 promise
const c = new LRUCache({
ttl: 100,
ignoreFetchAbort: true, // true 时会忽略传递给 fetchMethod 的 AbortSignal 对象发出的中止事件,除非 signal 未定义,否则仍然会对结果进行缓存。
allowStaleOnFetchAbort: true, // 当传递给 fetchMethod 的 AbortSignal 触发 “abort” 事件时,设置为 true 可以从缓存中返回一个过期的值。
fetchMethod: async (key, oldValue, { signal }) => {
// 不要将 signal 作为参数传递给 fetch 函数
const res = await fetch(`https://slow-backend-server/${key}`)
return await res.json()
},
})
// 会在 100 毫秒后返回过期的值,并进行值的更新。
const val = await c.fetch('key', { signal: AbortSignal.timeout(100) })
dispose(value, key, reason)
(只读)
当元素从缓存中删除时调用的函数。
原因为下列字符串之一:
evict
: 为添加的元素倒空间set
: 元素被覆盖delete
: 使用cache.delete(key)
或cache.clear()
删除了该元素
ttlResolution
检查过期的元素的时间间隔. 默认值为 1,意味着每毫秒会检查一遍列表,确保没有过期的元素。设置为较高的值会提升性能。
ttlAutopurge
是否立即删除过期的元素,这可能会显著降低性能,特别是当缓存存储大量项目时。
updateAgeOnGet
当调用 get 方法时会将元素的存活时间重置,让元素不会过期。但不保证其他方式不会将元素删除。
API
set(key, value, [{ size, sizeCalculation, ttl, noDisposeOnSet, start, status }])
向缓存添加一个值。
可选选项对象可能包含如上所述的 ttl 和 sizeCalculation,默认为缓存对象上的设置。
get(key, { updateAgeOnGet, allowStale, status } = {}) => value
从缓存中获取值
async fetch(key, options = {}) => Promise
options 包含下列属性
updateAgeOnGet
allowStale
size
sizeCalculation
ttl
noDisposeOnSet
forceRefresh
status
signal
context
peek(key, { allowStale } = {}) => value
类似于 get()
,但不会更新最近或删除过期的元素。
如果元素过期,则返回 undefined,除非在缓存或选项对象中设置 allowStale。
has(key, { updateAgeOnHas, status } = {}) => Boolean
检查缓存中是否存在对应元素
delete(key)
从缓存中删除对应元素
clear()
清空缓存
keys()
返回一个所有 keys 的 generator,从最多使用到最近使用。
rkeys()
返回一个所有 keys 的 generator,从最近使用到最多使用,刚好和keys相反。
values()
返回一个所有 values 的 generator,从最多使用到最近使用。
rvalues()
返回一个所有 values 的 generator,从最近使用到最多使用,刚好和 values 相反。
entries()
返回一个所有 键值对 的 generator, 从最多使用到最近使用。
rentries()
返回一个所有 键值对 的 generator, 从最近使用到最多使用,与 entries 相反。
find(fn, [getOptions])
类似于 Array.find() 返回符合条件的值。
LRU 是什么
LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。最近使用最少(LRU)缓存按使用顺序组织项目,可以快速识别哪个项目在最长时间内没有使用过。
一个应用场景是当B端用户读取页面时,需要从磁盘读取静态文件而后通过http/https进行请求的响应,而每次请求到来时若都去磁盘进行读取,速度是很慢的,如果在读取一次之后将需要响应的文件添加到内存中,下一次读取时相应速率会发生质的提升,因此有了 lru 。这也引申出一个问题,如果缓存较小或需要缓存的文件很大,需要怎么处理?
优点:
- 超快速访问。LRU缓存按最近使用到最后使用的顺序存储项目。时间复杂度为 O(1)。
- 超快的更新。每次访问项目时,更新缓存都需要 O(1)。
缺点:
- 占用空间较大。LRU缓存 存储 n 项元素时 同时 需要长度为 n 的链表以及容量为 n 的 hashmap,空间复杂度O(n)
转载自:https://juejin.cn/post/7222951736650416187