
Company News
AWS Security Hub Adds Socket for Supply Chain Security
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.
一个简单的 JavaScript 缓存管理,支持浏览器端和 node 端。
主要包含 2 个类:
npm install cache2
yarn add cache2
pnpm add cache2
如果你的项目使用的是原生方式开发,可以在浏览器中使用 script 标签直接引入文件,并使用全局变量 cache2。
npm 包的 cache2/dist 目录下提供了 UMD 包 cache2.js 以及 cache2.min.js。你也可以通过 UNPKG 下载到本地进行使用。或者直接使用 UNPKG 线上版本 注意版本 。
Storage 自定义缓存后,存取数据时自动处理序列化和解析数据。
import { Storage } from 'cache2';
const local = new Storage(window.localStorage);
local.set('foo', { a: 1, b: ['bar'], c: ['x', 2, 3] });
local.get('foo');
// { a: 1, b: ['bar'], c: ['x', 2, 3] }
local.del('foo');
local.get('foo');
// null
Cache 默认命名空间名称 'default',使用内存缓存。
import { Cache } from 'cache2';
const myCache = new Cache({
stdTTL: 60 * 1000
max: 20
});
myCache.set('foo', { baz: 42 });
myCache.get('foo');
// { baz: 42 }
// 60 seconds later ...
myCache.get('foo');
// undefined
Cache 自定义缓存后,存取数据时自动处理序列化和解析数据。
import { Cache } from 'cache2';
const myCache = new Cache('namespace', {
storage: localStorage,
stdTTL: 60 * 1000
});
myCache.set('foo', { baz: 42 }, 10 * 1000);
myCache.set('bar', 'abc');
myCache.get('foo');
// { baz: 42 }
myCache.get('bar');
// 'abc'
// 10 seconds later ...
myCache.get('foo');
// undefined
myCache.get('bar');
// 'abc'
// 60 seconds later ...
myCache.get('bar');
// undefined
数据存储管理。适用于简单的内存缓存、浏览器存储。
import { Storage, StorageOptions } from 'cache2';
declare class Storage<ValueType = any> {
constructor(storage?: TStorage, options?: Partial<StorageOptions>);
}
const memory = new Storage();
const memory2 = new Storage(undefined, options);
const local = new Storage(window.localStorage, options);
const session = new Storage(window.sessionStorage, options);
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| needParsed | 存取数据时是否需要序列化和解析数据。 如果使用内置的内存缓存,默认 false,如果自定义 storage 默认 true。 | boolean | - |
| replacer | 数据存储时序列化的参数,透传给 JSON.stringify 的 replacer 参数。仅在 needParsed=true 时生效。 | (key: string, value: any) => any | - |
| reviver | 数据获取时转换的参数,透传给 JSON.parse 的 reviver 参数。仅在 needParsed=true 时生效。 | (key: string, value: any) => any | - |
| prefix | 缓存键前缀。便于管理同域名下的不同项目缓存。 | string | - |
获取存储的数据。如果键值存在返回键值,否则返回 null。
const local = new Storage(window.localStorage);
local.set('foo', { baz: 42 });
local.get('foo');
// { baz: 42 }
存储数据。
const local = new Storage(window.localStorage);
local.set('foo', { baz: 42 });
local.get('foo');
// { baz: 42 }
删除存储的数据。
const local = new Storage(window.localStorage);
local.set('foo', { baz: 42 });
local.get('foo');
// { baz: 42 }
local.del('foo');
local.get('foo');
// null
清除存储的所有键。
⚠️注意:该方法调用 storage.clear(),可能会将同域下的不同实例的所有键都清除。如果要避免这种情况,建议使用 Cache。
const local = new Storage(window.localStorage);
local.set('foo', { baz: 42 });
local.get('foo');
// { baz: 42 }
local.clear();
local.get('foo');
// null
功能丰富的数据存储管理,支持 自定义缓存 命名空间 数据过期时间 限制缓存数量 自定义事件。
import { Cache, CacheOptions } from 'cache2';
declare class Cache<ValueType = any> extends Emitter<(key: string, value: ValueType) => void> {
constructor(options?: Partial<CacheOptions>);
constructor(namespace: string, options?: Partial<CacheOptions>);
}
// 如果不传命名空间,默认 'default'。
const memory = new Cache();
const memory2 = new Cache(options);
const memory3 = new Cache('namespace', options);
const local = new Storage({ storage: window.localStorage });
const local2 = new Storage('namespace', { storage: window.localStorage });
const session = new Storage({ storage: window.sessionStorage });
const session2 = new Storage('namespace', { storage: window.sessionStorage });
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| storage | 自定义数据存储器,支持 localStorage sessionStorage。默认使用内置的内存缓存。 | TStorage | - |
| max | 最大缓存数据数量。-1 表示无限制。 | number | -1 |
| maxStrategy | 当达到最大缓存数量限制时的缓存策略。'limited' 表示达到限制数量后不存入数据,保存时返回 false。'replaced' 表示优先替换快过期的数据,如果都是一样的过期时间(0),按照先入先出规则处理,保存时始终返回 true。 | 'limited' | 'replaced' | 'limited' |
| stdTTL | 相对当前时间的数据存活时间,应用于当前实例的所有缓存数据。单位为毫秒,0 表示无期限。 | number | 0 |
| checkperiod | 定时检查过期数据,单位毫秒。如果小于等于 0 表示不启动定时器检查。 | number | 0 |
| needParsed | 存取数据时是否需要序列化和解析数据。 如果使用内置的内存缓存,默认 false,如果自定义 storage 默认 true。 | boolean | - |
| replacer | 数据存储时序列化的参数,透传给 JSON.stringify 的 replacer 参数。仅在 needParsed=true 时生效。 | (key: string, value: any) => any | - |
| reviver | 数据获取时转换的参数,透传给 JSON.parse 的 reviver 参数。仅在 needParsed=true 时生效。 | (key: string, value: any) => any | - |
| prefix | 缓存键前缀。 | string | cache2_ |
⚠️ 注意:同一个命名空间的缓存是共享的。意味着命名空间名称相同的情况下,不同实例之间共用同一份缓存数据。建议自定义命名空间名称,避免不同实例的缓存数据冲突
import { Cache } from 'cache2';
const myCache = new Cache(namespace?, options?);
设置缓存数据。
如果设置成功返回 true,否则返回 false。
myCache.set('myKey', { foo: 'bar', baz: 42 }, 5 * 60 * 1000);
// true
设置多个缓存数据。
如果全部设置成功返回 true,否则返回 false。
myCache.mset([
{ key: 'myKey', value: { foo: 'bar', baz: 42 }, ttl: 5 * 60 * 1000 },
{ key: 'myKey2', value: { a: 1, b: 2 } },
{ key: 'myKey3', value: 'abc' }
]);
// true
获取缓存值。
如果找到该值,则返回该值。如果未找到或已过期,则返回 undefined。
myCache.set('myKey', obj, 5 * 60 * 1000);
myCache.get('myKey');
// { foo: 'bar', baz: 42 }
myCache.get('myKey2');
// undefined
获取缓存值并从缓存中删除键。
如果找到该值,则返回该值,并从缓存中删除该键。如果未找到或已过期,则返回 undefined。
myCache.set('myKey', 'myValue'); // true
myCache.has('myKey'); // true
myCache.take('myKey'); // 'myValue'
myCache.has('myKey'); // false
获取多个缓存值。
如果找到对应键名的值,返回一个具有键值对的对象。如果未找到或已过期,则返回一个空对象 {}。
myCache.mset([
{ key: 'myKey', value: { foo: 'bar', baz: 42 }, ttl: 5 * 60 * 1000 },
{ key: 'myKey2', value: { a: 1, b: 2 } },
{ key: 'myKey3', value: 'abc' }
]);
myCache.mget(['myKey', 'myKey2']);
// {
// myKey: { foo: 'bar', baz: 42 },
// myKey2: { a: 1, b: 2 }
// }
获取全部缓存值。
返回一个具有键值对的对象。
myCache.mset([
{ key: 'myKey', value: { foo: 'bar', baz: 42 }, ttl: 5 * 60 * 1000 },
{ key: 'myKey2', value: { a: 1, b: 2 } },
{ key: 'myKey3', value: 'abc' }
]);
myCache.getAll();
// {
// myKey: { foo: 'bar', baz: 42 },
// myKey2: { a: 1, b: 2 }
// myKey3: 'abc'
// }
获取全部键名的数组。
返回全部键名的数组。
myCache.set('bar', 1);
myCache.set('foo', 2);
myCache.keys(); // ['bar', 'foo']
判断是否存在某个键。
如果包含该键返回 true,否则返回 false。
myCache.has('foo'); // false
myCache.set('foo', 1);
myCache.has('foo'); // true
删除一个或多个键值。
返回已删除的数量。
myCache.set('myKey', { foo: 'bar', baz: 42 });
myCache.del('myKey'); // 1
myCache.del('not found'); // 0
myCache.mset([
{ key: 'myKey', value: { foo: 'bar', baz: 42 }, ttl: 5 * 60 * 1000 },
{ key: 'myKey2', value: { a: 1, b: 2 } },
{ key: 'myKey3', value: 'abc' }
]);
myCache.del(['myKey', 'myKey2']); // 2
清除全部缓存的数据(当前命名空间)。
myCache.set('bar', 1);
myCache.set('foo', 2);
myCache.keys(); // ['bar', 'foo']
myCache.clear();
myCache.keys(); // []
更新缓存键值的数据存活时间。
myCache.set('myKey', { foo: 'bar', baz: 42 }, 5 * 60 * 1000);
myCache.ttl('myKey', 2 * 60 * 1000);
// true
myCache.ttl('not found', 1000);
// false
获取某个键的过期时间戳。有以下返回值:
undefined。ttl 为 0,返回 0。const myCache = new Cache({ stdTTL: 5 * 1000 });
// 假如 Date.now() = 1673330000000
myCache.set('ttlKey', 'expireData');
myCache.set('noTtlKey', 'nonExpireData', 0);
myCache.getTtl('ttlKey'); // 1673330005000
myCache.getTtl('noTtlKey'); // 0
myCache.getTtl('unknownKey'); // undefined
获取某个键值的最后修改时间。有以下返回值:
undefined。const myCache = new Cache();
// Date.now() = 1673330000000
myCache.set('myKey', 'foo');
myCache.getLastModified('myKey'); // 1673330000000
// 5000ms later ...
myCache.set('myKey', 'bar');
myCache.getLastModified('myKey'); // 1673330005000
启动定时校验过期数据。
注意,如果没有设置 checkperiod 将不会触发定时器。
// 设置 checkperiod 之后自动生效
const myCache = new Cache({
checkperiod: 10 * 60 * 1000 // 10分钟检查一次数据是否过期
});
// 停止定时校验过期数据
myCache.stopCheckperiod();
// 启动定时校验过期数据
myCache.startCheckperiod();
停止定时校验过期数据。参考 startCheckperiod 示例。
成功设置键值后触发。
myCache.on('set', (key, value) => {
// do something
});
删除键值后触发。
myCache.on('del', (key, value) => {
// do something
});
校验数据过期后触发。
注意,如果校验数据过期,会先删除数据触发 del 事件,然后再触发 expired 事件。
myCache.on('expired', (key, value) => {
// do something
});
import { Cache } from 'cache2';
const apiCache = new Cache('api', { stdTTL: 10 * 60 * 1000 });
// ...
import { Cache } from 'cache2';
const fileObjectUrlCache = new Cache('fileObjectUrl', { max: 20, maxStrategy: 'replaced' });
fileObjectUrlCache.on('del', (key, value) => {
URL.revokeObjectURL(value);
});
fileObjectUrlCache.set(fssid, URL.createObjectURL(file));
sessionStorage、localStorage 支持过期时间import { Cache } from 'cache2';
const localCache = new Cache({
storage: localStorage,
stdTTL: 5 * 60 * 1000 // 默认数据留存时间为5分钟
});
localCache.set('num', 1); // 该数据默认留存5分钟
localCache.set('str', 'foo', 10 * 60 * 1000); // 该数据留存10分钟
自定义 storage 对象需要包含 getItem setItem removeItem。
例如,微信端的同步缓存等。
import { Cache } from 'cache2';
const wxStorage = {
getItem(key: string) {
return wx.getStorageSync(key);
},
setItem(key: string, value: any) {
wx.setStorageSync(key, value);
},
removeItem(key: string) {
wx.removeStorageSync(key);
}
};
const wxCache = new Cache('namespace', {
storage: wxStorage,
needParsed: false,
stdTTL: 5 * 60 * 1000 // 设置默认数据留存时间为5分钟
});
wxCache.set('num', 1); // 该数据默认留存5分钟
wxCache.set('str', 'foo', 10 * 60 * 1000); // 该数据留存10分钟
可以单独实现一个获取缓存键的方法。
import { isObject } from 'ut2';
const wm = new WeakMap();
const getCacheKey = (obj: string | Blob) => {
if (!isObject(obj)) {
return String(obj);
}
if (!wm.get(obj)) {
wm.set(obj, uniqueId());
}
return wm.get(obj) as string;
};
const myCache = new Cache('namespace');
myCache.set(getCacheKey(someKey), someValue);
myCache.get(getCacheKey(someKey));
FAQs
一个简单的 JavaScript 缓存管理,支持浏览器端和 node 端。
The npm package cache2 receives a total of 2,144 weekly downloads. As such, cache2 popularity was classified as popular.
We found that cache2 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.

Research
/Security News
Popular npm packages keyv and cacheable compromised.

Security News
A misconfiguration gave three Anthropic models internet access, and one, believing it was in a simulation, shipped a credential-stealing package to PyPI.