mm_cachebase 1.4.6 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +225 -709
- package/compatibility_table.md +63 -0
- package/index.js +503 -1418
- package/package.json +41 -35
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# mm_cachebase
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
一个轻量级的本地缓存类库,提供了与Redis兼容的缓存操作接口,支持过期时间设置、哈希表操作、数值操作、字符串操作等功能,以及完整的事件通知系统。
|
|
4
|
+
|
|
5
|
+
## 特点
|
|
6
|
+
|
|
7
|
+
- **Redis兼容API**:实现了与npm redis模块相似的接口,便于无缝切换
|
|
8
|
+
- **轻量级设计**:纯JavaScript实现,无外部依赖
|
|
9
|
+
- **完整的事件系统**:支持前置/后置/错误事件,便于日志记录和访问控制
|
|
10
|
+
- **过期时间管理**:支持设置和查询键的过期时间
|
|
11
|
+
- **丰富的数据类型支持**:支持字符串、哈希表等Redis常见数据类型
|
|
4
12
|
|
|
5
13
|
## 安装
|
|
6
14
|
|
|
@@ -38,9 +46,7 @@ async function example() {
|
|
|
38
46
|
const cache = new CacheBase();
|
|
39
47
|
```
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
- `list`: 存储缓存数据的数组
|
|
43
|
-
- `func`: 到期通知函数(可选)
|
|
49
|
+
创建一个新的缓存实例。缓存实例基于EventEmitter,支持完整的事件系统。
|
|
44
50
|
|
|
45
51
|
### 基本操作
|
|
46
52
|
|
|
@@ -51,14 +57,14 @@ await cache.set(key, value, maxAge)
|
|
|
51
57
|
- `key`: 缓存键名
|
|
52
58
|
- `value`: 缓存的值
|
|
53
59
|
- `maxAge`: 过期时间(秒),-1表示永不过期
|
|
54
|
-
- 返回:
|
|
60
|
+
- 返回: 'OK'
|
|
55
61
|
|
|
56
62
|
#### 获取缓存
|
|
57
63
|
```javascript
|
|
58
64
|
await cache.get(key)
|
|
59
65
|
```
|
|
60
66
|
- `key`: 缓存键名
|
|
61
|
-
- 返回: 缓存值,不存在则返回
|
|
67
|
+
- 返回: 缓存值,不存在则返回null
|
|
62
68
|
|
|
63
69
|
#### 删除缓存
|
|
64
70
|
```javascript
|
|
@@ -67,239 +73,138 @@ await cache.del(key)
|
|
|
67
73
|
- `key`: 缓存键名
|
|
68
74
|
- 返回: 成功返回1,失败返回0
|
|
69
75
|
|
|
70
|
-
####
|
|
76
|
+
#### 设置并获取旧值
|
|
71
77
|
```javascript
|
|
72
|
-
await cache.
|
|
78
|
+
await cache.getset(key, value, maxAge)
|
|
73
79
|
```
|
|
74
|
-
-
|
|
75
|
-
- 返回:
|
|
80
|
+
- 先获取旧值,然后设置新值
|
|
81
|
+
- 返回: 旧值,不存在则返回null
|
|
76
82
|
|
|
77
|
-
####
|
|
83
|
+
#### 批量设置缓存
|
|
78
84
|
```javascript
|
|
79
|
-
await cache.
|
|
85
|
+
await cache.mset(keys, values, maxAge)
|
|
80
86
|
```
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
#### 设置/查询过期时间
|
|
86
|
-
```javascript
|
|
87
|
-
await cache.ttl(key, maxAge)
|
|
88
|
-
```
|
|
89
|
-
- `maxAge`: 不传则查询剩余时间,传入则设置新的过期时间
|
|
90
|
-
- 返回: 查询时返回剩余秒数,设置时返回1
|
|
91
|
-
|
|
92
|
-
### 数值操作
|
|
93
|
-
|
|
94
|
-
#### 增加整数
|
|
95
|
-
```javascript
|
|
96
|
-
await cache.addInt(key, num)
|
|
97
|
-
```
|
|
98
|
-
- `num`: 要增加的数值,可以为负数
|
|
99
|
-
- 返回: 计算后的结果
|
|
87
|
+
- `keys`: 键名数组
|
|
88
|
+
- `values`: 值数组
|
|
89
|
+
- 返回: 'OK'
|
|
100
90
|
|
|
101
|
-
####
|
|
91
|
+
#### 批量获取缓存
|
|
102
92
|
```javascript
|
|
103
|
-
await cache.
|
|
93
|
+
await cache.mget(...keys)
|
|
104
94
|
```
|
|
105
|
-
-
|
|
106
|
-
|
|
107
|
-
### 字符串操作
|
|
95
|
+
- `keys`: 一个或多个键名
|
|
96
|
+
- 返回: 值数组
|
|
108
97
|
|
|
109
|
-
####
|
|
98
|
+
#### 判断键是否存在
|
|
110
99
|
```javascript
|
|
111
|
-
await cache.
|
|
100
|
+
await cache.exists(...keys)
|
|
112
101
|
```
|
|
113
|
-
-
|
|
114
|
-
- 返回:
|
|
102
|
+
- `keys`: 一个或多个键名
|
|
103
|
+
- 返回: 存在的键数量
|
|
115
104
|
|
|
116
|
-
|
|
117
|
-
```javascript
|
|
118
|
-
await cache.getrange(key, start, end)
|
|
119
|
-
```
|
|
120
|
-
- 获取缓存字符串的指定范围
|
|
121
|
-
- 返回: 截取的字符串
|
|
105
|
+
### 过期时间操作
|
|
122
106
|
|
|
123
|
-
####
|
|
107
|
+
#### 设置过期时间
|
|
124
108
|
```javascript
|
|
125
|
-
await cache.
|
|
109
|
+
await cache.expire(key, maxAge)
|
|
126
110
|
```
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
### 哈希表操作
|
|
130
|
-
|
|
131
|
-
#### 设置哈希表字段
|
|
132
|
-
```javascript
|
|
133
|
-
await cache.hset(key, field, value)
|
|
134
|
-
```
|
|
135
|
-
- `key`: 哈希表的键名
|
|
136
|
-
- `field`: 字段名
|
|
137
|
-
- `value`: 字段值
|
|
111
|
+
- `maxAge`: 过期时间(秒)
|
|
138
112
|
- 返回: 成功返回1,失败返回0
|
|
139
113
|
|
|
140
|
-
####
|
|
114
|
+
#### 查询剩余过期时间
|
|
141
115
|
```javascript
|
|
142
|
-
await cache.
|
|
116
|
+
await cache.ttl(key)
|
|
143
117
|
```
|
|
144
|
-
- 返回:
|
|
118
|
+
- 返回: 剩余秒数,不存在或永不过期返回-1
|
|
145
119
|
|
|
146
|
-
####
|
|
120
|
+
#### 移除过期时间
|
|
147
121
|
```javascript
|
|
148
|
-
await cache.
|
|
122
|
+
await cache.persist(key)
|
|
149
123
|
```
|
|
150
124
|
- 返回: 成功返回1,失败返回0
|
|
151
125
|
|
|
152
|
-
|
|
153
|
-
```javascript
|
|
154
|
-
await cache.hkeys(key)
|
|
155
|
-
```
|
|
156
|
-
- 返回: 键名数组
|
|
157
|
-
|
|
158
|
-
#### 获取哈希表所有值
|
|
159
|
-
```javascript
|
|
160
|
-
await cache.hvals(key)
|
|
161
|
-
```
|
|
162
|
-
- 返回: 值数组
|
|
163
|
-
|
|
164
|
-
### 列表操作
|
|
165
|
-
|
|
166
|
-
#### 设置列表
|
|
167
|
-
```javascript
|
|
168
|
-
await cache.list_set(key, value, maxAge)
|
|
169
|
-
```
|
|
170
|
-
- 设置一个数组类型的缓存
|
|
171
|
-
|
|
172
|
-
#### 添加列表元素
|
|
173
|
-
```javascript
|
|
174
|
-
await cache.list_add(key, value)
|
|
175
|
-
```
|
|
176
|
-
- 向数组末尾添加元素
|
|
177
|
-
- 返回: 成功返回1,失败返回-1
|
|
178
|
-
|
|
179
|
-
#### 从左侧推入元素
|
|
180
|
-
```javascript
|
|
181
|
-
await cache.lpush(key, ...values)
|
|
182
|
-
```
|
|
183
|
-
- 从列表左侧添加一个或多个元素
|
|
184
|
-
- 返回: 操作后的列表长度
|
|
185
|
-
|
|
186
|
-
#### 从左侧弹出元素
|
|
187
|
-
```javascript
|
|
188
|
-
await cache.lpop(key)
|
|
189
|
-
```
|
|
190
|
-
- 从列表左侧移除并返回一个元素
|
|
191
|
-
- 返回: 弹出的元素,列表为空返回null
|
|
192
|
-
|
|
193
|
-
#### 从右侧推入元素
|
|
194
|
-
```javascript
|
|
195
|
-
await cache.rpush(key, ...values)
|
|
196
|
-
```
|
|
197
|
-
- 从列表右侧添加一个或多个元素
|
|
198
|
-
- 返回: 操作后的列表长度
|
|
199
|
-
|
|
200
|
-
#### 从右侧弹出元素
|
|
201
|
-
```javascript
|
|
202
|
-
await cache.rpop(key)
|
|
203
|
-
```
|
|
204
|
-
- 从列表右侧移除并返回一个元素
|
|
205
|
-
- 返回: 弹出的元素,列表为空返回null
|
|
206
|
-
|
|
207
|
-
#### 获取列表长度
|
|
208
|
-
```javascript
|
|
209
|
-
await cache.llen(key)
|
|
210
|
-
```
|
|
211
|
-
- 返回: 列表长度,键不存在返回0
|
|
126
|
+
### 数值操作
|
|
212
127
|
|
|
213
|
-
####
|
|
128
|
+
#### 增加整数
|
|
214
129
|
```javascript
|
|
215
|
-
await cache.
|
|
130
|
+
await cache.incr(key)
|
|
216
131
|
```
|
|
217
|
-
-
|
|
132
|
+
- 将键的值加1
|
|
133
|
+
- 返回: 增加后的值
|
|
218
134
|
|
|
219
|
-
####
|
|
135
|
+
#### 增加指定整数
|
|
220
136
|
```javascript
|
|
221
|
-
await cache.
|
|
137
|
+
await cache.incrby(key, increment)
|
|
222
138
|
```
|
|
223
|
-
-
|
|
139
|
+
- `increment`: 要增加的整数
|
|
140
|
+
- 返回: 增加后的值
|
|
224
141
|
|
|
225
|
-
####
|
|
142
|
+
#### 减少整数
|
|
226
143
|
```javascript
|
|
227
|
-
await cache.
|
|
144
|
+
await cache.decr(key)
|
|
228
145
|
```
|
|
229
|
-
-
|
|
230
|
-
|
|
231
|
-
### 集合操作
|
|
146
|
+
- 将键的值减1
|
|
147
|
+
- 返回: 减少后的值
|
|
232
148
|
|
|
233
|
-
####
|
|
149
|
+
#### 减少指定整数
|
|
234
150
|
```javascript
|
|
235
|
-
await cache.
|
|
151
|
+
await cache.decrby(key, decrement)
|
|
236
152
|
```
|
|
237
|
-
-
|
|
238
|
-
- 返回:
|
|
153
|
+
- `decrement`: 要减少的整数
|
|
154
|
+
- 返回: 减少后的值
|
|
239
155
|
|
|
240
|
-
####
|
|
156
|
+
#### 增加浮点数
|
|
241
157
|
```javascript
|
|
242
|
-
await cache.
|
|
158
|
+
await cache.incrbyfloat(key, increment)
|
|
243
159
|
```
|
|
244
|
-
-
|
|
245
|
-
- 返回:
|
|
160
|
+
- `increment`: 要增加的浮点数
|
|
161
|
+
- 返回: 增加后的值
|
|
246
162
|
|
|
247
|
-
|
|
248
|
-
```javascript
|
|
249
|
-
await cache.smembers(key)
|
|
250
|
-
```
|
|
251
|
-
- 返回: 成员数组,键不存在返回空数组
|
|
163
|
+
### 字符串操作
|
|
252
164
|
|
|
253
|
-
####
|
|
165
|
+
#### 追加字符串
|
|
254
166
|
```javascript
|
|
255
|
-
await cache.
|
|
167
|
+
await cache.append(key, value)
|
|
256
168
|
```
|
|
257
|
-
-
|
|
169
|
+
- 在已有字符串后追加新字符串
|
|
170
|
+
- 返回: 追加后的字符串长度
|
|
258
171
|
|
|
259
|
-
####
|
|
172
|
+
#### 获取字符串长度
|
|
260
173
|
```javascript
|
|
261
|
-
await cache.
|
|
174
|
+
await cache.strlen(key)
|
|
262
175
|
```
|
|
263
|
-
- 返回:
|
|
176
|
+
- 返回: 字符串长度
|
|
264
177
|
|
|
265
|
-
###
|
|
178
|
+
### 哈希表操作
|
|
266
179
|
|
|
267
|
-
####
|
|
180
|
+
#### 设置哈希表字段
|
|
268
181
|
```javascript
|
|
269
|
-
await cache.
|
|
182
|
+
await cache.hset(key, field, value)
|
|
270
183
|
```
|
|
271
|
-
-
|
|
272
|
-
-
|
|
184
|
+
- `key`: 哈希表的键名
|
|
185
|
+
- `field`: 字段名
|
|
186
|
+
- `value`: 字段值
|
|
187
|
+
- 返回: 成功返回1,失败返回0
|
|
273
188
|
|
|
274
|
-
####
|
|
189
|
+
#### 获取哈希表字段
|
|
275
190
|
```javascript
|
|
276
|
-
await cache.
|
|
191
|
+
await cache.hget(key, field)
|
|
277
192
|
```
|
|
278
|
-
-
|
|
279
|
-
- `withScores`: 是否返回分数
|
|
280
|
-
- 返回: 成员数组或[成员, 分数]数组
|
|
193
|
+
- 返回: 字段值,不存在则返回null
|
|
281
194
|
|
|
282
|
-
####
|
|
195
|
+
#### 获取哈希表所有字段和值
|
|
283
196
|
```javascript
|
|
284
|
-
await cache.
|
|
197
|
+
await cache.hgetall(key)
|
|
285
198
|
```
|
|
286
|
-
-
|
|
287
|
-
- 返回: 成功返回1,成员不存在返回0
|
|
199
|
+
- 返回: 包含所有字段和值的对象
|
|
288
200
|
|
|
289
|
-
####
|
|
201
|
+
#### 删除哈希表字段
|
|
290
202
|
```javascript
|
|
291
|
-
await cache.
|
|
203
|
+
await cache.hdel(key, field)
|
|
292
204
|
```
|
|
293
|
-
- 返回:
|
|
205
|
+
- 返回: 成功返回1,失败返回0
|
|
294
206
|
|
|
295
|
-
###
|
|
296
|
-
|
|
297
|
-
#### 排序
|
|
298
|
-
```javascript
|
|
299
|
-
await cache.sort(key, way, obj_key)
|
|
300
|
-
```
|
|
301
|
-
- `way`: 'asc'升序或'desc'降序
|
|
302
|
-
- `obj_key`: 如果数组元素是对象,指定排序的键
|
|
207
|
+
### 键操作
|
|
303
208
|
|
|
304
209
|
#### 获取所有键名
|
|
305
210
|
```javascript
|
|
@@ -308,12 +213,18 @@ await cache.keys(pattern)
|
|
|
308
213
|
- `pattern`: 支持*通配符的匹配模式
|
|
309
214
|
- 返回: 匹配的键名数组
|
|
310
215
|
|
|
216
|
+
#### 获取键数量
|
|
217
|
+
```javascript
|
|
218
|
+
await cache.dbsize()
|
|
219
|
+
```
|
|
220
|
+
- 返回: 缓存中的键数量
|
|
221
|
+
|
|
311
222
|
#### 清空缓存
|
|
312
223
|
```javascript
|
|
313
|
-
await cache.
|
|
224
|
+
await cache.flushdb()
|
|
314
225
|
```
|
|
315
|
-
-
|
|
316
|
-
-
|
|
226
|
+
- 清空所有缓存
|
|
227
|
+
- 返回: 'OK'
|
|
317
228
|
|
|
318
229
|
#### 销毁缓存实例
|
|
319
230
|
```javascript
|
|
@@ -321,207 +232,38 @@ await cache.dispose()
|
|
|
321
232
|
```
|
|
322
233
|
- 清理所有资源,移除所有监听器
|
|
323
234
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
### 基本缓存操作
|
|
327
|
-
```javascript
|
|
328
|
-
const cache = new CacheBase();
|
|
329
|
-
|
|
330
|
-
async function example() {
|
|
331
|
-
// 设置缓存
|
|
332
|
-
await cache.set("user", "张三", 60); // 60秒后过期
|
|
333
|
-
|
|
334
|
-
// 获取缓存
|
|
335
|
-
const user = await cache.get("user");
|
|
336
|
-
console.log(user); // 输出: 张三
|
|
337
|
-
|
|
338
|
-
// 检查是否存在
|
|
339
|
-
const exists = await cache.has("user");
|
|
340
|
-
console.log(exists); // 输出: 1
|
|
341
|
-
|
|
342
|
-
// 删除缓存
|
|
343
|
-
await cache.del("user");
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
### 哈希表操作示例
|
|
348
|
-
```javascript
|
|
349
|
-
async function hashExample() {
|
|
350
|
-
// 设置哈希表字段
|
|
351
|
-
await cache.hset("user:123", "name", "张三");
|
|
352
|
-
await cache.hset("user:123", "age", 30);
|
|
353
|
-
await cache.hset("user:123", "email", "zhangsan@example.com");
|
|
354
|
-
|
|
355
|
-
// 获取哈希表字段
|
|
356
|
-
const name = await cache.hget("user:123", "name");
|
|
357
|
-
console.log(name); // 输出: 张三
|
|
358
|
-
|
|
359
|
-
// 获取所有键名
|
|
360
|
-
const keys = await cache.hkeys("user:123");
|
|
361
|
-
console.log(keys); // 输出: ["name", "age", "email"]
|
|
362
|
-
|
|
363
|
-
// 获取所有值
|
|
364
|
-
const values = await cache.hvals("user:123");
|
|
365
|
-
console.log(values); // 输出: ["张三", 30, "zhangsan@example.com"]
|
|
366
|
-
|
|
367
|
-
// 删除字段
|
|
368
|
-
await cache.hdel("user:123", "email");
|
|
369
|
-
}
|
|
370
|
-
```
|
|
235
|
+
### 兼容方法(保持向后兼容)
|
|
371
236
|
|
|
372
|
-
|
|
237
|
+
#### 添加缓存(仅当键不存在时)
|
|
373
238
|
```javascript
|
|
374
|
-
|
|
375
|
-
// 设置列表
|
|
376
|
-
await cache.list_set("tasks", ["任务1", "任务2"], 300);
|
|
377
|
-
|
|
378
|
-
// 添加元素到末尾
|
|
379
|
-
await cache.list_add("tasks", "任务3");
|
|
380
|
-
|
|
381
|
-
// 从左侧推入元素
|
|
382
|
-
await cache.lpush("tasks", "任务0");
|
|
383
|
-
|
|
384
|
-
// 从右侧推入元素
|
|
385
|
-
await cache.rpush("tasks", "任务4");
|
|
386
|
-
|
|
387
|
-
// 从左侧弹出元素
|
|
388
|
-
const task0 = await cache.lpop("tasks");
|
|
389
|
-
console.log("弹出任务:", task0); // 输出: 任务0
|
|
390
|
-
|
|
391
|
-
// 从右侧弹出元素
|
|
392
|
-
const task4 = await cache.rpop("tasks");
|
|
393
|
-
console.log("弹出任务:", task4); // 输出: 任务4
|
|
394
|
-
|
|
395
|
-
// 获取列表长度
|
|
396
|
-
const length = await cache.llen("tasks");
|
|
397
|
-
console.log("任务数量:", length); // 输出: 3
|
|
398
|
-
|
|
399
|
-
// 获取列表
|
|
400
|
-
const tasks = await cache.list_get("tasks");
|
|
401
|
-
console.log("任务列表:", tasks); // 输出: ["任务1", "任务2", "任务3"]
|
|
402
|
-
|
|
403
|
-
// 排序
|
|
404
|
-
await cache.sort("tasks", "asc");
|
|
405
|
-
}
|
|
239
|
+
await cache.add(key, value, maxAge)
|
|
406
240
|
```
|
|
241
|
+
- 返回: 添加成功返回值,已存在返回0
|
|
407
242
|
|
|
408
|
-
|
|
243
|
+
#### 检查键是否存在
|
|
409
244
|
```javascript
|
|
410
|
-
|
|
411
|
-
// 添加集合成员
|
|
412
|
-
await cache.sadd("users", "张三");
|
|
413
|
-
await cache.sadd("users", "李四");
|
|
414
|
-
await cache.sadd("users", "王五");
|
|
415
|
-
|
|
416
|
-
// 尝试添加重复成员
|
|
417
|
-
const result = await cache.sadd("users", "张三");
|
|
418
|
-
console.log("添加重复成员结果:", result); // 输出: 0
|
|
419
|
-
|
|
420
|
-
// 判断成员是否存在
|
|
421
|
-
const exists = await cache.sismember("users", "张三");
|
|
422
|
-
console.log("张三是否在用户集合中:", exists); // 输出: 1
|
|
423
|
-
|
|
424
|
-
// 获取集合所有成员
|
|
425
|
-
const members = await cache.smembers("users");
|
|
426
|
-
console.log("用户集合:", members); // 输出: ["张三", "李四", "王五"]
|
|
427
|
-
|
|
428
|
-
// 获取集合大小
|
|
429
|
-
const size = await cache.scard("users");
|
|
430
|
-
console.log("集合大小:", size); // 输出: 3
|
|
431
|
-
|
|
432
|
-
// 删除成员
|
|
433
|
-
await cache.srem("users", "李四");
|
|
434
|
-
}
|
|
245
|
+
await cache.has(key)
|
|
435
246
|
```
|
|
247
|
+
- 返回: 存在返回1,不存在返回0
|
|
436
248
|
|
|
437
|
-
|
|
249
|
+
#### 增加浮点数(兼容方法)
|
|
438
250
|
```javascript
|
|
439
|
-
|
|
440
|
-
// 添加有序集合成员
|
|
441
|
-
await cache.zadd("scores", 95, "张三");
|
|
442
|
-
await cache.zadd("scores", 88, "李四");
|
|
443
|
-
await cache.zadd("scores", 92, "王五");
|
|
444
|
-
|
|
445
|
-
// 获取有序集合范围(升序)
|
|
446
|
-
const ascendingScores = await cache.zrange("scores", 0, -1, true);
|
|
447
|
-
console.log("分数排序(升序):", ascendingScores);
|
|
448
|
-
// 输出: ["李四", 88, "王五", 92, "张三", 95]
|
|
449
|
-
|
|
450
|
-
// 获取指定成员分数
|
|
451
|
-
const zhangScore = await cache.zscore("scores", "张三");
|
|
452
|
-
console.log("张三的分数:", zhangScore); // 输出: 95
|
|
453
|
-
|
|
454
|
-
// 删除成员
|
|
455
|
-
await cache.zrem("scores", "李四");
|
|
456
|
-
|
|
457
|
-
// 再次获取有序集合
|
|
458
|
-
const remainingScores = await cache.zrange("scores", 0, -1);
|
|
459
|
-
console.log("剩余成员:", remainingScores); // 输出: ["王五", "张三"]
|
|
460
|
-
}
|
|
251
|
+
await cache.addFloat(key, num)
|
|
461
252
|
```
|
|
253
|
+
- `num`: 要增加的浮点数
|
|
254
|
+
- 返回: 计算后的结果
|
|
462
255
|
|
|
463
|
-
|
|
256
|
+
#### 追加字符串(兼容方法)
|
|
464
257
|
```javascript
|
|
465
|
-
|
|
466
|
-
// 设置缓存
|
|
467
|
-
await cache.set("token", "abc123", 30);
|
|
468
|
-
|
|
469
|
-
// 查询剩余时间
|
|
470
|
-
const ttl = await cache.ttl("token");
|
|
471
|
-
console.log(`剩余${ttl}秒`);
|
|
472
|
-
|
|
473
|
-
// 延长过期时间
|
|
474
|
-
await cache.ttl("token", 60);
|
|
475
|
-
|
|
476
|
-
// 设置永不过期
|
|
477
|
-
await cache.ttl("token", -1);
|
|
478
|
-
}
|
|
258
|
+
await cache.addStr(key, str)
|
|
479
259
|
```
|
|
260
|
+
- 返回: 追加后的完整字符串
|
|
480
261
|
|
|
481
|
-
|
|
262
|
+
#### 清空匹配缓存(兼容方法)
|
|
482
263
|
```javascript
|
|
483
|
-
|
|
484
|
-
// 获取所有以user开头的键
|
|
485
|
-
const keys = await cache.keys("user*");
|
|
486
|
-
|
|
487
|
-
// 清空所有以temp开头的缓存
|
|
488
|
-
await cache.clear("temp*");
|
|
489
|
-
|
|
490
|
-
// 清空所有缓存
|
|
491
|
-
await cache.clear();
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
### 事件系统使用示例
|
|
495
|
-
```javascript
|
|
496
|
-
async function eventExample() {
|
|
497
|
-
// 设置操作的前置事件
|
|
498
|
-
cache.on('set_before', (data) => {
|
|
499
|
-
console.log(`即将设置键: ${data.key}`);
|
|
500
|
-
|
|
501
|
-
// 示例:进行数据验证
|
|
502
|
-
if (typeof data.value === 'string' && data.value.length > 100) {
|
|
503
|
-
console.log('值长度过长,取消设置');
|
|
504
|
-
data.cancel = true; // 取消操作
|
|
505
|
-
}
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
// 获取操作的后置事件
|
|
509
|
-
cache.on('get_after', (data) => {
|
|
510
|
-
console.log(`获取键 ${data.key} 的结果: ${data.result}`);
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
// 尝试设置缓存
|
|
514
|
-
await cache.set("test", "这是一个测试值");
|
|
515
|
-
|
|
516
|
-
// 获取缓存
|
|
517
|
-
const value = await cache.get("test");
|
|
518
|
-
|
|
519
|
-
// 错误事件监听
|
|
520
|
-
cache.on('get_error', (data) => {
|
|
521
|
-
console.error(`获取键 ${data.key} 时出错: ${data.error.message}`);
|
|
522
|
-
});
|
|
523
|
-
}
|
|
264
|
+
await cache.clear(pattern)
|
|
524
265
|
```
|
|
266
|
+
- `pattern`: 可选,支持*通配符
|
|
525
267
|
|
|
526
268
|
## 事件系统
|
|
527
269
|
|
|
@@ -553,385 +295,159 @@ cache.off('event_name', callback);
|
|
|
553
295
|
|
|
554
296
|
### 支持的事件类型
|
|
555
297
|
|
|
556
|
-
每个缓存操作都有对应的前置事件(`_before`)、后置事件(`_after`)和错误事件(`_error
|
|
298
|
+
每个缓存操作都有对应的前置事件(`_before`)、后置事件(`_after`)和错误事件(`_error`)。
|
|
557
299
|
|
|
558
300
|
#### 基本操作事件
|
|
559
301
|
- `set_before`, `set_after`, `set_error`
|
|
560
302
|
- `get_before`, `get_after`, `get_error`
|
|
561
303
|
- `del_before`, `del_after`, `del_error`
|
|
562
304
|
- `exists_before`, `exists_after`, `exists_error`
|
|
563
|
-
- `
|
|
305
|
+
- `mset_before`, `mset_after`, `mset_error`
|
|
306
|
+
- `mget_before`, `mget_after`, `mget_error`
|
|
307
|
+
|
|
308
|
+
#### 过期时间操作事件
|
|
309
|
+
- `expire_before`, `expire_after`, `expire_error`
|
|
310
|
+
- `ttl_before`, `ttl_after`, `ttl_error`
|
|
311
|
+
|
|
312
|
+
#### 数值操作事件
|
|
313
|
+
- `incr_before`, `incr_after`, `incr_error`
|
|
314
|
+
- `decr_before`, `decr_after`, `decr_error`
|
|
315
|
+
- `incrby_before`, `incrby_after`, `incrby_error`
|
|
316
|
+
- `decrby_before`, `decrby_after`, `decrby_error`
|
|
317
|
+
- `incrbyfloat_before`, `incrbyfloat_after`, `incrbyfloat_error`
|
|
318
|
+
|
|
319
|
+
#### 字符串操作事件
|
|
320
|
+
- `append_before`, `append_after`, `append_error`
|
|
321
|
+
- `strlen_before`, `strlen_after`, `strlen_error`
|
|
564
322
|
|
|
565
323
|
#### 哈希表操作事件
|
|
566
324
|
- `hset_before`, `hset_after`, `hset_error`
|
|
567
325
|
- `hget_before`, `hget_after`, `hget_error`
|
|
326
|
+
- `hgetall_before`, `hgetall_after`, `hgetall_error`
|
|
568
327
|
- `hdel_before`, `hdel_after`, `hdel_error`
|
|
569
|
-
- `hkeys_before`, `hkeys_after`, `hkeys_error`
|
|
570
|
-
- `hvals_before`, `hvals_after`, `hvals_error`
|
|
571
|
-
|
|
572
|
-
#### 列表操作事件
|
|
573
|
-
- `lpush_before`, `lpush_after`, `lpush_error`
|
|
574
|
-
- `lpop_before`, `lpop_after`, `lpop_error`
|
|
575
|
-
- `rpush_before`, `rpush_after`, `rpush_error`
|
|
576
|
-
- `rpop_before`, `rpop_after`, `rpop_error`
|
|
577
|
-
- `llen_before`, `llen_after`, `llen_error`
|
|
578
|
-
- `list_set_before`, `list_set_after`, `list_set_error`
|
|
579
|
-
- `list_add_before`, `list_add_after`, `list_add_error`
|
|
580
|
-
- `list_clear_before`, `list_clear_after`, `list_clear_error`
|
|
581
|
-
|
|
582
|
-
#### 集合操作事件
|
|
583
|
-
- `sadd_before`, `sadd_after`, `sadd_error`
|
|
584
|
-
- `srem_before`, `srem_after`, `srem_error`
|
|
585
|
-
- `smembers_before`, `smembers_after`, `smembers_error`
|
|
586
|
-
- `sismember_before`, `sismember_after`, `sismember_error`
|
|
587
|
-
- `scard_before`, `scard_after`, `scard_error`
|
|
588
|
-
|
|
589
|
-
#### 有序集合操作事件
|
|
590
|
-
- `zadd_before`, `zadd_after`, `zadd_error`
|
|
591
|
-
- `zrange_before`, `zrange_after`, `zrange_error`
|
|
592
|
-
- `zrem_before`, `zrem_after`, `zrem_error`
|
|
593
|
-
- `zscore_before`, `zscore_after`, `zscore_error`
|
|
594
|
-
|
|
595
|
-
#### 其他操作事件
|
|
596
|
-
- `mset_before`, `mset_after`, `mset_error`
|
|
597
|
-
- `setex_before`, `setex_after`, `setex_error`
|
|
598
|
-
- `setnx_before`, `setnx_after`, `setnx_error`
|
|
599
|
-
- `add_before`, `add_after`, `add_error`
|
|
600
|
-
- `addFloat_before`, `addFloat_after`, `addFloat_error`
|
|
601
|
-
- `addStr_before`, `addStr_after`, `addStr_error`
|
|
602
|
-
- `setrange_before`, `setrange_after`, `setrange_error`
|
|
603
328
|
|
|
604
|
-
|
|
329
|
+
#### 键操作事件
|
|
330
|
+
- `keys_before`, `keys_after`, `keys_error`
|
|
331
|
+
- `dbsize_before`, `dbsize_after`, `dbsize_error`
|
|
332
|
+
- `flushdb_before`, `flushdb_after`, `flushdb_error`
|
|
333
|
+
- `dispose_before`, `dispose_after`, `dispose_error`
|
|
605
334
|
|
|
606
|
-
|
|
335
|
+
### 事件使用示例
|
|
607
336
|
|
|
608
337
|
```javascript
|
|
338
|
+
const cache = new CacheBase();
|
|
339
|
+
|
|
609
340
|
// 监听设置操作的前置事件
|
|
610
341
|
cache.on('set_before', (data) => {
|
|
611
342
|
console.log('即将设置键:', data.key, '值:', data.value);
|
|
612
343
|
|
|
613
|
-
//
|
|
614
|
-
if (typeof data.value
|
|
615
|
-
console.log('
|
|
344
|
+
// 数据验证示例
|
|
345
|
+
if (typeof data.value === 'string' && data.value.length > 100) {
|
|
346
|
+
console.log('值长度过长,取消设置');
|
|
616
347
|
data.cancel = true; // 取消操作
|
|
617
348
|
}
|
|
618
349
|
});
|
|
619
350
|
|
|
620
|
-
//
|
|
621
|
-
cache.on('
|
|
622
|
-
console.log(
|
|
623
|
-
|
|
624
|
-
// 实现简单的访问控制
|
|
625
|
-
const restrictedKeys = ['admin_data', 'sensitive_info'];
|
|
626
|
-
if (restrictedKeys.includes(data.key) && !userHasPermission()) {
|
|
627
|
-
console.log('无权限访问此键,取消获取操作');
|
|
628
|
-
data.cancel = true; // 取消操作
|
|
629
|
-
}
|
|
351
|
+
// 监听获取操作的后置事件
|
|
352
|
+
cache.on('get_after', (data) => {
|
|
353
|
+
console.log(`获取键 ${data.key} 的结果: ${data.result}`);
|
|
630
354
|
});
|
|
631
355
|
|
|
632
|
-
//
|
|
633
|
-
cache.on('
|
|
634
|
-
console.
|
|
635
|
-
|
|
636
|
-
// 防止删除特定成员
|
|
637
|
-
if (data.value.member === 'protected_member') {
|
|
638
|
-
console.log('保护成员不能删除,取消操作');
|
|
639
|
-
data.cancel = true;
|
|
640
|
-
}
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
// 监听删除键操作的前置事件
|
|
644
|
-
cache.on('del_before', (data) => {
|
|
645
|
-
console.log('尝试删除键:', data.key);
|
|
646
|
-
|
|
647
|
-
// 防止删除系统键
|
|
648
|
-
if (data.key.startsWith('system:')) {
|
|
649
|
-
console.log('系统键不能删除,取消操作');
|
|
650
|
-
data.cancel = true;
|
|
651
|
-
}
|
|
356
|
+
// 错误事件监听
|
|
357
|
+
cache.on('get_error', (data) => {
|
|
358
|
+
console.error(`获取键 ${data.key} 时出错: ${data.error.message}`);
|
|
652
359
|
});
|
|
653
360
|
```
|
|
654
361
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
以下是一个完整的示例,展示如何使用事件系统进行缓存操作的全面监控、日志记录和访问控制:
|
|
362
|
+
## 使用示例
|
|
658
363
|
|
|
364
|
+
### 基本缓存操作
|
|
659
365
|
```javascript
|
|
660
|
-
const
|
|
366
|
+
const cache = new CacheBase();
|
|
661
367
|
|
|
662
|
-
async function
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
// 1. 实现统一的操作日志记录
|
|
666
|
-
const operations = ['get', 'set', 'del', 'exists', 'hget', 'hset',
|
|
667
|
-
'lpush', 'lpop', 'rpush', 'rpop', 'sadd', 'srem',
|
|
668
|
-
'smembers', 'zadd', 'zrange'];
|
|
669
|
-
|
|
670
|
-
// 为所有操作添加日志记录
|
|
671
|
-
operations.forEach(op => {
|
|
672
|
-
// 记录操作开始
|
|
673
|
-
cache.on(`${op}_before`, (data) => {
|
|
674
|
-
console.log(`[CACHE] 开始 ${op} 操作`, {
|
|
675
|
-
key: data.key,
|
|
676
|
-
value: data.value,
|
|
677
|
-
timestamp: new Date().toISOString()
|
|
678
|
-
});
|
|
679
|
-
});
|
|
680
|
-
|
|
681
|
-
// 记录操作成功完成
|
|
682
|
-
cache.on(`${op}_after`, (data) => {
|
|
683
|
-
console.log(`[CACHE] ${op} 操作成功`, {
|
|
684
|
-
key: data.key,
|
|
685
|
-
result: data.result,
|
|
686
|
-
timestamp: new Date().toISOString()
|
|
687
|
-
});
|
|
688
|
-
});
|
|
689
|
-
|
|
690
|
-
// 记录操作失败
|
|
691
|
-
cache.on(`${op}_error`, (data) => {
|
|
692
|
-
console.error(`[CACHE] ${op} 操作失败`, {
|
|
693
|
-
key: data.key,
|
|
694
|
-
error: data.error.message,
|
|
695
|
-
timestamp: new Date().toISOString()
|
|
696
|
-
});
|
|
697
|
-
});
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
// 2. 实现缓存操作统计
|
|
701
|
-
const stats = {
|
|
702
|
-
totalOperations: 0,
|
|
703
|
-
successfulOperations: 0,
|
|
704
|
-
failedOperations: 0,
|
|
705
|
-
canceledOperations: 0,
|
|
706
|
-
operationTypes: {}
|
|
707
|
-
};
|
|
708
|
-
|
|
709
|
-
// 更新统计信息
|
|
710
|
-
operations.forEach(op => {
|
|
711
|
-
cache.on(`${op}_before`, () => {
|
|
712
|
-
stats.totalOperations++;
|
|
713
|
-
stats.operationTypes[op] = (stats.operationTypes[op] || 0) + 1;
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
cache.on(`${op}_after`, (data) => {
|
|
717
|
-
if (op === 'get' && data.result === null) {
|
|
718
|
-
// 可以特殊处理缓存未命中的情况
|
|
719
|
-
console.log(`[CACHE] 缓存未命中: ${data.key}`);
|
|
720
|
-
}
|
|
721
|
-
stats.successfulOperations++;
|
|
722
|
-
});
|
|
723
|
-
|
|
724
|
-
cache.on(`${op}_error`, () => {
|
|
725
|
-
stats.failedOperations++;
|
|
726
|
-
});
|
|
727
|
-
});
|
|
728
|
-
|
|
729
|
-
// 3. 实现复杂的访问控制
|
|
730
|
-
const accessControl = {
|
|
731
|
-
// 定义哪些用户角色可以访问哪些键模式
|
|
732
|
-
permissions: {
|
|
733
|
-
'admin': ['*'],
|
|
734
|
-
'user': ['user:*', 'public:*'],
|
|
735
|
-
'guest': ['public:*']
|
|
736
|
-
},
|
|
737
|
-
|
|
738
|
-
// 当前用户角色
|
|
739
|
-
currentRole: 'user'
|
|
740
|
-
};
|
|
741
|
-
|
|
742
|
-
// 为敏感操作添加访问控制
|
|
743
|
-
['get', 'del', 'hget', 'hdel'].forEach(op => {
|
|
744
|
-
cache.on(`${op}_before`, (data) => {
|
|
745
|
-
const hasPermission = accessControl.permissions[accessControl.currentRole].some(pattern => {
|
|
746
|
-
// 简单的通配符匹配实现
|
|
747
|
-
if (pattern === '*') return true;
|
|
748
|
-
const regexPattern = pattern.replace(/\*/g, '.*');
|
|
749
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
750
|
-
return regex.test(data.key);
|
|
751
|
-
});
|
|
752
|
-
|
|
753
|
-
if (!hasPermission) {
|
|
754
|
-
console.warn(`[SECURITY] 拒绝访问: 用户 ${accessControl.currentRole} 尝试访问键 ${data.key}`);
|
|
755
|
-
data.cancel = true;
|
|
756
|
-
stats.canceledOperations++;
|
|
757
|
-
}
|
|
758
|
-
});
|
|
759
|
-
});
|
|
760
|
-
|
|
761
|
-
// 4. 执行一些测试操作
|
|
762
|
-
console.log('执行测试操作...');
|
|
763
|
-
|
|
764
|
-
// 应该成功的操作
|
|
765
|
-
await cache.set('user:123:name', '张三');
|
|
766
|
-
await cache.hset('user:123:profile', 'email', 'zhangsan@example.com');
|
|
767
|
-
await cache.sadd('user:123:tags', 'vip');
|
|
768
|
-
|
|
769
|
-
// 尝试访问无权限的键
|
|
770
|
-
const restrictedData = await cache.get('admin:settings');
|
|
771
|
-
console.log('受限访问结果:', restrictedData); // 应该是 null
|
|
368
|
+
async function example() {
|
|
369
|
+
// 设置缓存
|
|
370
|
+
await cache.set("user", "张三", 60); // 60秒后过期
|
|
772
371
|
|
|
773
|
-
//
|
|
774
|
-
const
|
|
775
|
-
console.log(
|
|
372
|
+
// 获取缓存
|
|
373
|
+
const user = await cache.get("user");
|
|
374
|
+
console.log(user); // 输出: 张三
|
|
776
375
|
|
|
777
|
-
//
|
|
778
|
-
|
|
779
|
-
console.log(
|
|
376
|
+
// 检查是否存在
|
|
377
|
+
const exists = await cache.exists("user");
|
|
378
|
+
console.log(exists); // 输出: 1
|
|
780
379
|
|
|
781
|
-
//
|
|
782
|
-
await cache.
|
|
380
|
+
// 删除缓存
|
|
381
|
+
await cache.del("user");
|
|
783
382
|
}
|
|
784
|
-
|
|
785
|
-
// 运行示例
|
|
786
|
-
eventSystemExample().catch(console.error);
|
|
787
383
|
```
|
|
788
384
|
|
|
789
|
-
###
|
|
790
|
-
|
|
791
|
-
#### 基本操作事件数据
|
|
385
|
+
### 哈希表操作示例
|
|
792
386
|
```javascript
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
//
|
|
808
|
-
|
|
809
|
-
key: 'test_key',
|
|
810
|
-
cancel: false
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
// get_after 事件数据
|
|
814
|
-
{
|
|
815
|
-
key: 'test_key',
|
|
816
|
-
result: 'test_value'
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
// exists_before 事件数据
|
|
820
|
-
{
|
|
821
|
-
key: 'test_key',
|
|
822
|
-
cancel: false
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
// exists_after 事件数据
|
|
826
|
-
{
|
|
827
|
-
key: 'test_key',
|
|
828
|
-
result: 1 // 1表示存在,0表示不存在
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
// dispose_before 事件数据
|
|
832
|
-
{
|
|
833
|
-
cancel: false
|
|
387
|
+
async function hashExample() {
|
|
388
|
+
// 设置哈希表字段
|
|
389
|
+
await cache.hset("user:123", "name", "张三");
|
|
390
|
+
await cache.hset("user:123", "age", 30);
|
|
391
|
+
await cache.hset("user:123", "email", "zhangsan@example.com");
|
|
392
|
+
|
|
393
|
+
// 获取哈希表字段
|
|
394
|
+
const name = await cache.hget("user:123", "name");
|
|
395
|
+
console.log(name); // 输出: 张三
|
|
396
|
+
|
|
397
|
+
// 获取所有字段和值
|
|
398
|
+
const user = await cache.hgetall("user:123");
|
|
399
|
+
console.log(user); // 输出: { name: "张三", age: 30, email: "zhangsan@example.com" }
|
|
400
|
+
|
|
401
|
+
// 删除字段
|
|
402
|
+
await cache.hdel("user:123", "email");
|
|
834
403
|
}
|
|
835
|
-
|
|
836
|
-
// dispose_after 事件无参数
|
|
837
404
|
```
|
|
838
405
|
|
|
839
|
-
|
|
406
|
+
### 数值操作示例
|
|
840
407
|
```javascript
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
//
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
// lpop_before/lpop_after 事件数据
|
|
863
|
-
{
|
|
864
|
-
key: 'list_key',
|
|
865
|
-
cancel: false // lpop_after 中包含 result
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
// rpop_before/rpop_after 事件数据
|
|
869
|
-
{
|
|
870
|
-
key: 'list_key',
|
|
871
|
-
cancel: false // rpop_after 中包含 result
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
// llen_before/llen_after 事件数据
|
|
875
|
-
{
|
|
876
|
-
key: 'list_key',
|
|
877
|
-
cancel: false // llen_after 中包含 result
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
// srem_before 事件数据
|
|
881
|
-
{
|
|
882
|
-
key: 'set_key',
|
|
883
|
-
value: { member: 'member1' },
|
|
884
|
-
cancel: false
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
// smembers_before/smembers_after 事件数据
|
|
888
|
-
{
|
|
889
|
-
key: 'set_key',
|
|
890
|
-
cancel: false // smembers_after 中包含 result 数组
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
// sismember_before 事件数据
|
|
894
|
-
{
|
|
895
|
-
key: 'set_key',
|
|
896
|
-
value: { member: 'member1' },
|
|
897
|
-
cancel: false
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
// scard_before/scard_after 事件数据
|
|
901
|
-
{
|
|
902
|
-
key: 'set_key',
|
|
903
|
-
cancel: false // scard_after 中包含 result
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// zrange_before 事件数据
|
|
907
|
-
{
|
|
908
|
-
key: 'zset_key',
|
|
909
|
-
value: { start: 0, stop: -1, withScores: false },
|
|
910
|
-
cancel: false
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
// zrem_before 事件数据
|
|
914
|
-
{
|
|
915
|
-
key: 'zset_key',
|
|
916
|
-
value: { member: 'zmember1' },
|
|
917
|
-
cancel: false
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
// zscore_before 事件数据
|
|
921
|
-
{
|
|
922
|
-
key: 'zset_key',
|
|
923
|
-
value: { member: 'zmember1' },
|
|
924
|
-
cancel: false
|
|
408
|
+
async function numberExample() {
|
|
409
|
+
// 设置初始值
|
|
410
|
+
await cache.set("counter", 10);
|
|
411
|
+
|
|
412
|
+
// 增加1
|
|
413
|
+
const incr = await cache.incr("counter");
|
|
414
|
+
console.log("增加后:", incr); // 输出: 11
|
|
415
|
+
|
|
416
|
+
// 增加指定值
|
|
417
|
+
const incrby = await cache.incrby("counter", 5);
|
|
418
|
+
console.log("增加5后:", incrby); // 输出: 16
|
|
419
|
+
|
|
420
|
+
// 减少1
|
|
421
|
+
const decr = await cache.decr("counter");
|
|
422
|
+
console.log("减少后:", decr); // 输出: 15
|
|
423
|
+
|
|
424
|
+
// 浮点数操作
|
|
425
|
+
await cache.set("price", 99.99);
|
|
426
|
+
const incrFloat = await cache.incrbyfloat("price", 0.01);
|
|
427
|
+
console.log("浮点数增加后:", incrFloat); // 输出: 100
|
|
925
428
|
}
|
|
429
|
+
```
|
|
926
430
|
|
|
927
|
-
|
|
431
|
+
### 批量操作示例
|
|
928
432
|
```javascript
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
433
|
+
async function batchExample() {
|
|
434
|
+
// 批量设置
|
|
435
|
+
await cache.mset(["key1", "key2", "key3"], ["value1", "value2", "value3"]);
|
|
436
|
+
|
|
437
|
+
// 批量获取
|
|
438
|
+
const values = await cache.mget("key1", "key2", "key3");
|
|
439
|
+
console.log("批量获取:", values); // 输出: ["value1", "value2", "value3"]
|
|
440
|
+
|
|
441
|
+
// 检查多个键是否存在
|
|
442
|
+
const existsCount = await cache.exists("key1", "key2", "nonexistent");
|
|
443
|
+
console.log("存在的键数量:", existsCount); // 输出: 2
|
|
444
|
+
|
|
445
|
+
// 获取键数量
|
|
446
|
+
const count = await cache.dbsize();
|
|
447
|
+
console.log("键总数:", count);
|
|
448
|
+
|
|
449
|
+
// 清空所有缓存
|
|
450
|
+
await cache.flushdb();
|
|
935
451
|
}
|
|
936
452
|
```
|
|
937
453
|
|
|
@@ -939,10 +455,10 @@ eventSystemExample().catch(console.error);
|
|
|
939
455
|
|
|
940
456
|
1. 所有操作方法都是异步的,需要使用async/await或Promise处理
|
|
941
457
|
2. 过期时间单位为秒,-1表示永不过期
|
|
942
|
-
3.
|
|
943
|
-
4.
|
|
944
|
-
5.
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
458
|
+
3. 缓存数据存储在内存中,重启后数据会丢失
|
|
459
|
+
4. 事件回调函数中的 `cancel` 标志只在前置事件中有效,后置事件中修改不会产生效果
|
|
460
|
+
5. 所有事件参数都遵循统一的格式,包含key、value、result、error和cancel等字段
|
|
461
|
+
|
|
462
|
+
## 许可证
|
|
463
|
+
|
|
464
|
+
MIT
|