mm_cachebase 1.4.6 → 1.6.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/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
- - 返回: 缓存值,不存在则返回undefined
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
- #### 添加缓存
71
- ```javascript
72
- await cache.add(key, value, maxAge)
73
- ```
74
- - 只在键不存在时添加缓存
75
- - 返回: 添加成功返回值,已存在返回0
76
-
77
- #### 判断键是否存在
78
- ```javascript
79
- await cache.has(key)
80
- ```
81
- - 返回: 存在返回1,不存在返回0
82
-
83
- ### 过期时间操作
84
-
85
- #### 设置/查询过期时间
86
- ```javascript
87
- await cache.ttl(key, maxAge)
88
- ```
89
- - `maxAge`: 不传则查询剩余时间,传入则设置新的过期时间
90
- - 返回: 查询时返回剩余秒数,设置时返回1
91
-
92
- ### 数值操作
93
-
94
- #### 增加整数
76
+ #### 设置并获取旧值
95
77
  ```javascript
96
- await cache.addInt(key, num)
78
+ await cache.getset(key, value, maxAge)
97
79
  ```
98
- - `num`: 要增加的数值,可以为负数
99
- - 返回: 计算后的结果
80
+ - 先获取旧值,然后设置新值
81
+ - 返回: 旧值,不存在则返回null
100
82
 
101
- #### 增加浮点数
83
+ #### 批量设置缓存
102
84
  ```javascript
103
- await cache.addFloat(key, num)
85
+ await cache.mset(keys, values, maxAge)
104
86
  ```
105
- - 用法同addInt,支持浮点数
87
+ - `keys`: 键名数组
88
+ - `values`: 值数组
89
+ - 返回: 'OK'
106
90
 
107
- ### 字符串操作
108
-
109
- #### 追加字符串
91
+ #### 批量获取缓存
110
92
  ```javascript
111
- await cache.addStr(key, str)
93
+ await cache.mget(...keys)
112
94
  ```
113
- - 在已有字符串后追加新字符串
114
- - 返回: 追加后的完整字符串
115
-
116
- #### 获取子字符串
117
- ```javascript
118
- await cache.getrange(key, start, end)
119
- ```
120
- - 获取缓存字符串的指定范围
121
- - 返回: 截取的字符串
95
+ - `keys`: 一个或多个键名
96
+ - 返回: 值数组
122
97
 
123
- #### 替换字符串
98
+ #### 判断键是否存在
124
99
  ```javascript
125
- await cache.setrange(key, index, value)
100
+ await cache.exists(...keys)
126
101
  ```
127
- - 从指定位置替换字符串
102
+ - `keys`: 一个或多个键名
103
+ - 返回: 存在的键数量
128
104
 
129
- ### 哈希表操作
105
+ ### 过期时间操作
130
106
 
131
- #### 设置哈希表字段
107
+ #### 设置过期时间
132
108
  ```javascript
133
- await cache.hset(key, field, value)
109
+ await cache.expire(key, maxAge)
134
110
  ```
135
- - `key`: 哈希表的键名
136
- - `field`: 字段名
137
- - `value`: 字段值
111
+ - `maxAge`: 过期时间(秒)
138
112
  - 返回: 成功返回1,失败返回0
139
113
 
140
- #### 获取哈希表字段
114
+ #### 查询剩余过期时间
141
115
  ```javascript
142
- await cache.hget(key, field)
116
+ await cache.ttl(key)
143
117
  ```
144
- - 返回: 字段值,不存在则返回null
118
+ - 返回: 剩余秒数,不存在或永不过期返回-1
145
119
 
146
- #### 删除哈希表字段
120
+ #### 移除过期时间
147
121
  ```javascript
148
- await cache.hdel(key, field)
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.list_has(key, value)
130
+ await cache.incr(key)
216
131
  ```
217
- - 检查数组中是否包含指定元素
132
+ - 将键的值加1
133
+ - 返回: 增加后的值
218
134
 
219
- #### 获取数组片段
135
+ #### 增加指定整数
220
136
  ```javascript
221
- await cache.list_get(key, start, end)
137
+ await cache.incrby(key, increment)
222
138
  ```
223
- - 获取数组的指定范围元素
139
+ - `increment`: 要增加的整数
140
+ - 返回: 增加后的值
224
141
 
225
- #### 清空/重置数组
142
+ #### 减少整数
226
143
  ```javascript
227
- await cache.list_clear(key, value)
144
+ await cache.decr(key)
228
145
  ```
229
- - 清空数组或用新数组替换
230
-
231
- ### 集合操作
146
+ - 将键的值减1
147
+ - 返回: 减少后的值
232
148
 
233
- #### 添加集合成员
149
+ #### 减少指定整数
234
150
  ```javascript
235
- await cache.sadd(key, member)
151
+ await cache.decrby(key, decrement)
236
152
  ```
237
- - 向集合添加一个成员
238
- - 返回: 成功返回1,成员已存在返回0
153
+ - `decrement`: 要减少的整数
154
+ - 返回: 减少后的值
239
155
 
240
- #### 删除集合成员
156
+ #### 增加浮点数
241
157
  ```javascript
242
- await cache.srem(key, member)
158
+ await cache.incrbyfloat(key, increment)
243
159
  ```
244
- - 从集合移除一个成员
245
- - 返回: 成功返回1,成员不存在返回0
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.sismember(key, member)
167
+ await cache.append(key, value)
256
168
  ```
257
- - 返回: 存在返回1,不存在返回0
169
+ - 在已有字符串后追加新字符串
170
+ - 返回: 追加后的字符串长度
258
171
 
259
- #### 获取集合大小
172
+ #### 获取字符串长度
260
173
  ```javascript
261
- await cache.scard(key)
174
+ await cache.strlen(key)
262
175
  ```
263
- - 返回: 集合大小,键不存在返回0
176
+ - 返回: 字符串长度
264
177
 
265
- ### 有序集合操作
178
+ ### 哈希表操作
266
179
 
267
- #### 添加有序集合成员
180
+ #### 设置哈希表字段
268
181
  ```javascript
269
- await cache.zadd(key, score, member)
182
+ await cache.hset(key, field, value)
270
183
  ```
271
- - 向有序集合添加一个成员
272
- - 返回: 成功返回1,成员已存在返回0
184
+ - `key`: 哈希表的键名
185
+ - `field`: 字段名
186
+ - `value`: 字段值
187
+ - 返回: 成功返回1,失败返回0
273
188
 
274
- #### 获取有序集合范围
189
+ #### 获取哈希表字段
275
190
  ```javascript
276
- await cache.zrange(key, start, stop, withScores)
191
+ await cache.hget(key, field)
277
192
  ```
278
- - `start`/`stop`: 范围索引
279
- - `withScores`: 是否返回分数
280
- - 返回: 成员数组或[成员, 分数]数组
193
+ - 返回: 字段值,不存在则返回null
281
194
 
282
- #### 删除有序集合成员
195
+ #### 获取哈希表所有字段和值
283
196
  ```javascript
284
- await cache.zrem(key, member)
197
+ await cache.hgetall(key)
285
198
  ```
286
- - 从有序集合移除一个成员
287
- - 返回: 成功返回1,成员不存在返回0
199
+ - 返回: 包含所有字段和值的对象
288
200
 
289
- #### 获取成员分数
201
+ #### 删除哈希表字段
290
202
  ```javascript
291
- await cache.zscore(key, member)
203
+ await cache.hdel(key, field)
292
204
  ```
293
- - 返回: 成员分数,成员不存在返回null
294
-
295
- ### 其他操作
205
+ - 返回: 成功返回1,失败返回0
296
206
 
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.clear(pattern)
224
+ await cache.flushdb()
314
225
  ```
315
- - `pattern`: 可选,支持*通配符,清空匹配的键
316
- - 不传则清空所有缓存
226
+ - 清空所有缓存
227
+ - 返回: 'OK'
317
228
 
318
229
  #### 销毁缓存实例
319
230
  ```javascript
@@ -321,212 +232,45 @@ await cache.dispose()
321
232
  ```
322
233
  - 清理所有资源,移除所有监听器
323
234
 
324
- ## 使用示例
235
+ ### 兼容方法(保持向后兼容)
325
236
 
326
- ### 基本缓存操作
237
+ #### 添加缓存(仅当键不存在时)
327
238
  ```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
- ```
371
-
372
- ### 列表操作示例
373
- ```javascript
374
- async function listExample() {
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
- async function setExample() {
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
- async function sortedSetExample() {
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
- async function ttlExample() {
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
- async function batchExample() {
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
 
528
270
  CacheBase 提供了完整的事件系统,允许你监听各种缓存操作的前后事件,以便进行日志记录、数据验证或操作取消等功能。
529
271
 
272
+ > **性能优化说明**:从版本 1.6.0 开始,查询类方法(如 get、hget、mget、exists、ttl 等)不再触发事件,以提高高频查询操作的性能。
273
+
530
274
  ### 事件监听方法
531
275
 
532
276
  ```javascript
@@ -553,385 +297,146 @@ cache.off('event_name', callback);
553
297
 
554
298
  ### 支持的事件类型
555
299
 
556
- 每个缓存操作都有对应的前置事件(`_before`)、后置事件(`_after`)和错误事件(`_error`)。以下是主要支持的事件类型:
300
+ 每个缓存操作都有对应的前置事件(`_before`)、后置事件(`_after`)和错误事件(`_error`)。
557
301
 
558
302
  #### 基本操作事件
559
303
  - `set_before`, `set_after`, `set_error`
560
- - `get_before`, `get_after`, `get_error`
561
304
  - `del_before`, `del_after`, `del_error`
562
- - `exists_before`, `exists_after`, `exists_error`
563
- - `dispose_before`, `dispose_after`, `dispose_error`
305
+ - `mset_before`, `mset_after`, `mset_error`
306
+
307
+ #### 过期时间操作事件
308
+ - `expire_before`, `expire_after`, `expire_error`
309
+ - `persist_before`, `persist_after`, `persist_error`
310
+
311
+ #### 数值操作事件
312
+ - `incr_before`, `incr_after`, `incr_error`
313
+ - `decr_before`, `decr_after`, `decr_error`
314
+ - `incrby_before`, `incrby_after`, `incrby_error`
315
+ - `decrby_before`, `decrby_after`, `decrby_error`
316
+ - `incrbyfloat_before`, `incrbyfloat_after`, `incrbyfloat_error`
317
+
318
+ #### 字符串操作事件
319
+ - `append_before`, `append_after`, `append_error`
564
320
 
565
321
  #### 哈希表操作事件
566
322
  - `hset_before`, `hset_after`, `hset_error`
567
- - `hget_before`, `hget_after`, `hget_error`
568
323
  - `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
324
 
604
- ### 取消操作示例
325
+ #### 键操作事件
326
+ - `flushdb_before`, `flushdb_after`, `flushdb_error`
327
+ - `dispose_before`, `dispose_after`, `dispose_error`
605
328
 
606
- 在前置事件中,你可以通过设置 `cancel` 标志为 `true` 来取消操作:
329
+ ### 事件使用示例
607
330
 
608
331
  ```javascript
332
+ const cache = new CacheBase();
333
+
609
334
  // 监听设置操作的前置事件
610
335
  cache.on('set_before', (data) => {
611
336
  console.log('即将设置键:', data.key, '值:', data.value);
612
337
 
613
- // 检查值是否合法
614
- if (typeof data.value !== 'string' || data.value.length > 100) {
615
- console.log('值不合法,取消设置操作');
338
+ // 数据验证示例
339
+ if (typeof data.value === 'string' && data.value.length > 100) {
340
+ console.log('值长度过长,取消设置');
616
341
  data.cancel = true; // 取消操作
617
342
  }
618
343
  });
619
344
 
620
- // 监听获取操作的前置事件 - 实现访问控制
621
- cache.on('get_before', (data) => {
622
- console.log('尝试获取键:', data.key);
623
-
624
- // 实现简单的访问控制
625
- const restrictedKeys = ['admin_data', 'sensitive_info'];
626
- if (restrictedKeys.includes(data.key) && !userHasPermission()) {
627
- console.log('无权限访问此键,取消获取操作');
628
- data.cancel = true; // 取消操作
629
- }
630
- });
631
-
632
- // 监听集合删除操作的前置事件
633
- cache.on('srem_before', (data) => {
634
- console.log('尝试从集合', data.key, '中删除成员:', data.value.member);
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
- }
345
+ // 错误事件监听
346
+ cache.on('mset_error', (data) => {
347
+ console.error(`批量设置出错: ${data.error.message}`);
652
348
  });
653
349
  ```
654
350
 
655
- ### 完整事件系统示例
656
-
657
- 以下是一个完整的示例,展示如何使用事件系统进行缓存操作的全面监控、日志记录和访问控制:
351
+ ## 使用示例
658
352
 
353
+ ### 基本缓存操作
659
354
  ```javascript
660
- const CacheBase = require('./index.js');
355
+ const cache = new CacheBase();
661
356
 
662
- async function eventSystemExample() {
663
- const cache = new CacheBase();
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
357
+ async function example() {
358
+ // 设置缓存
359
+ await cache.set("user", "张三", 60); // 60秒后过期
772
360
 
773
- // 正常访问有权限的键
774
- const userName = await cache.get('user:123:name');
775
- console.log('用户名:', userName);
361
+ // 获取缓存
362
+ const user = await cache.get("user");
363
+ console.log(user); // 输出: 张三
776
364
 
777
- // 5. 显示操作统计
778
- console.log('\n操作统计:');
779
- console.log(stats);
365
+ // 检查是否存在
366
+ const exists = await cache.exists("user");
367
+ console.log(exists); // 输出: 1
780
368
 
781
- // 6. 清理资源
782
- await cache.dispose();
369
+ // 删除缓存
370
+ await cache.del("user");
783
371
  }
784
-
785
- // 运行示例
786
- eventSystemExample().catch(console.error);
787
372
  ```
788
373
 
789
- ### 事件参数格式示例
790
-
791
- #### 基本操作事件数据
374
+ ### 哈希表操作示例
792
375
  ```javascript
793
- // set_before 事件数据
794
- {
795
- key: 'test_key',
796
- value: 'test_value',
797
- cancel: false
798
- }
799
-
800
- // set_after 事件数据
801
- {
802
- key: 'test_key',
803
- value: 'test_value',
804
- result: 1
805
- }
806
-
807
- // get_before 事件数据
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
376
+ async function hashExample() {
377
+ // 设置哈希表字段
378
+ await cache.hset("user:123", "name", "张三");
379
+ await cache.hset("user:123", "age", 30);
380
+ await cache.hset("user:123", "email", "zhangsan@example.com");
381
+
382
+ // 获取哈希表字段
383
+ const name = await cache.hget("user:123", "name");
384
+ console.log(name); // 输出: 张三
385
+
386
+ // 获取所有字段和值
387
+ const user = await cache.hgetall("user:123");
388
+ console.log(user); // 输出: { name: "张三", age: 30, email: "zhangsan@example.com" }
389
+
390
+ // 删除字段
391
+ await cache.hdel("user:123", "email");
834
392
  }
835
-
836
- // dispose_after 事件无参数
837
393
  ```
838
394
 
839
- #### 复合操作事件数据
395
+ ### 数值操作示例
840
396
  ```javascript
841
- // hset_before 事件数据
842
- {
843
- key: 'hash_key',
844
- value: { field: 'field1', value: 'value1' },
845
- cancel: false
846
- }
847
-
848
- // hget_before 事件数据
849
- {
850
- key: 'hash_key',
851
- value: { field: 'field1' },
852
- cancel: false
853
- }
854
-
855
- // lpush_before 事件数据
856
- {
857
- key: 'list_key',
858
- value: { values: ['item1', 'item2'] },
859
- cancel: false
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
397
+ async function numberExample() {
398
+ // 设置初始值
399
+ await cache.set("counter", 10);
400
+
401
+ // 增加1
402
+ const incr = await cache.incr("counter");
403
+ console.log("增加后:", incr); // 输出: 11
404
+
405
+ // 增加指定值
406
+ const incrby = await cache.incrby("counter", 5);
407
+ console.log("增加5后:", incrby); // 输出: 16
408
+
409
+ // 减少1
410
+ const decr = await cache.decr("counter");
411
+ console.log("减少后:", decr); // 输出: 15
412
+
413
+ // 浮点数操作
414
+ await cache.set("price", 99.99);
415
+ const incrFloat = await cache.incrbyfloat("price", 0.01);
416
+ console.log("浮点数增加后:", incrFloat); // 输出: 100
925
417
  }
418
+ ```
926
419
 
927
- #### 过期时间操作事件数据
420
+ ### 批量操作示例
928
421
  ```javascript
929
- // setex_before 事件数据
930
- {
931
- key: 'setex_key',
932
- value: 'setex_value',
933
- ttl: 60,
934
- cancel: false
422
+ async function batchExample() {
423
+ // 批量设置
424
+ await cache.mset(["key1", "key2", "key3"], ["value1", "value2", "value3"]);
425
+
426
+ // 批量获取
427
+ const values = await cache.mget("key1", "key2", "key3");
428
+ console.log("批量获取:", values); // 输出: ["value1", "value2", "value3"]
429
+
430
+ // 检查多个键是否存在
431
+ const existsCount = await cache.exists("key1", "key2", "nonexistent");
432
+ console.log("存在的键数量:", existsCount); // 输出: 2
433
+
434
+ // 获取键数量
435
+ const count = await cache.dbsize();
436
+ console.log("键总数:", count);
437
+
438
+ // 清空所有缓存
439
+ await cache.flushdb();
935
440
  }
936
441
  ```
937
442
 
@@ -939,10 +444,10 @@ eventSystemExample().catch(console.error);
939
444
 
940
445
  1. 所有操作方法都是异步的,需要使用async/await或Promise处理
941
446
  2. 过期时间单位为秒,-1表示永不过期
942
- 3. 数组操作方法只能用于数组类型的缓存值
943
- 4. 键名支持*通配符匹配,可用于批量操作
944
- 5. 缓存数据存储在内存中,重启后数据会丢失
945
- 6. 事件回调函数中的 `cancel` 标志只在前置事件中有效,后置事件中修改不会产生效果
946
- 7. 当List、Set或Sorted Set类型的缓存变为空时,对应的键会被自动删除
947
- 8. 所有事件参数都遵循统一的格式,包含key、value、result、error和cancel等字段
948
- 9. 错误日志都添加了`[cachebase]`前缀,便于日志识别和过滤
447
+ 3. 缓存数据存储在内存中,重启后数据会丢失
448
+ 4. 事件回调函数中的 `cancel` 标志只在前置事件中有效,后置事件中修改不会产生效果
449
+ 5. 所有事件参数都遵循统一的格式,包含key、value、result、error和cancel等字段
450
+
451
+ ## 许可证
452
+
453
+ MIT